完善SSO单点登录

(cherry picked from commit e22363d061)
This commit is contained in:
puhui999 2023-04-07 10:15:21 +08:00 committed by shizhong
parent 1103f8ff39
commit fbff879504
4 changed files with 43 additions and 42 deletions

View File

@ -76,7 +76,14 @@ export const reqCheckApi = (data) => {
}
// ========== OAUTH 2.0 相关 ==========
export type scopesType = string[]
export interface paramsType {
responseType: string
clientId: string
redirectUri: string
state: string
scopes: scopesType
}
export const getAuthorize = (clientId) => {
return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId })
}
@ -87,8 +94,8 @@ export function authorize(
redirectUri: string,
state: string,
autoApprove: boolean,
checkedScopes: any,
uncheckedScopes: any
checkedScopes: scopesType,
uncheckedScopes: scopesType
) {
// 构建 scopes
const scopes = {}

View File

@ -9,19 +9,19 @@
>
<!-- 左上角的 logo + 系统标题 -->
<div class="flex items-center relative text-white">
<img src="@/assets/imgs/logo.png" alt="" class="w-48px h-48px mr-10px" />
<img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
</div>
<!-- 左边的背景图 + 欢迎语 -->
<div class="flex justify-center items-center h-[calc(100%-60px)]">
<TransitionGroup
appear
tag="div"
enter-active-class="animate__animated animate__bounceInLeft"
tag="div"
>
<img src="@/assets/svgs/login-box-bg.svg" key="1" alt="" class="w-350px" />
<div class="text-3xl text-white" key="2">{{ t('login.welcome') }}</div>
<div class="mt-5 font-normal text-white text-14px" key="3">
<img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />
<div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>
<div key="3" class="mt-5 font-normal text-white text-14px">
{{ t('login.message') }}
</div>
</TransitionGroup>
@ -31,7 +31,7 @@
<!-- 右上角的主题语言选择 -->
<div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end">
<div class="flex items-center @2xl:hidden @xl:hidden">
<img src="@/assets/imgs/logo.png" alt="" class="w-48px h-48px mr-10px" />
<img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
</div>
<div class="flex justify-end items-center space-x-10px">
@ -52,18 +52,15 @@
<QrCodeForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
<!-- 注册 -->
<RegisterForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
<!-- 三方登录 v-if触发组件初始化 -->
<SSOLoginVue
v-if="isSSO"
class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)"
/>
<!-- 三方登录 -->
<SSOLoginVue class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
</div>
</Transition>
</div>
</div>
</div>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import { underlineToHump } from '@/utils'
import { useDesign } from '@/hooks/web/useDesign'
@ -72,23 +69,11 @@ import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue } from './components'
import { RouteLocationNormalizedLoaded } from 'vue-router'
const { t } = useI18n()
const appStore = useAppStore()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('login')
// =======SSO======
const isSSO = ref(false)
const router = useRouter()
//
watch(
() => router.currentRoute.value,
(route: RouteLocationNormalizedLoaded) => {
if (route.name === 'SSOLogin') isSSO.value = true
},
{ immediate: true }
)
</script>
<style lang="scss" scoped>

View File

@ -279,7 +279,6 @@ const doSocialLogin = async (type: number) => {
watch(
() => currentRoute.value,
(route: RouteLocationNormalizedLoaded) => {
if (route.name === 'SSOLogin') setLoginState(LoginStateEnum.SSO)
redirect.value = route?.query?.redirect as string
},
{

View File

@ -1,6 +1,7 @@
<template>
<!-- 表单 -->
<div class="form-cont">
<div v-show="getShow" class="form-cont">
<!-- <LoginFormTitle style="width: 100%" />-->
<el-tabs class="form" style="float: none" value="uname">
<el-tab-pane :label="'三方授权(' + client.name + ')'" name="uname" />
</el-tabs>
@ -12,8 +13,8 @@
<el-checkbox-group v-model="loginForm.scopes">
<el-checkbox
v-for="scope in params.scopes"
:label="scope"
:key="scope"
:label="scope"
style="display: block; margin-bottom: -10px"
>{{ formatScope(scope) }}
</el-checkbox>
@ -24,8 +25,8 @@
<el-button
:loading="loading"
size="small"
type="primary"
style="width: 60%"
type="primary"
@click.prevent="handleAuthorize(true)"
>
<span v-if="!loading">同意授权</span>
@ -40,19 +41,15 @@
</div>
</template>
<script lang="ts" name="SSOLogin" setup>
import { authorize, getAuthorize } from '@/api/login'
// import LoginFormTitle from './LoginFormTitle.vue' // TODO
import { authorize, getAuthorize, paramsType, scopesType } from '@/api/login'
import { LoginStateEnum, useLoginState } from './useLogin'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
const { t } = useI18n()
const ssoForm = ref() // Ref
type scopesType = string[]
interface paramsType {
responseType: string
clientId: string
redirectUri: string
state: string
scopes: scopesType
}
const { getLoginState, setLoginState } = useLoginState()
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.SSO)
const loginForm = reactive<{ scopes: scopesType }>({
scopes: [] // scope
})
@ -116,6 +113,7 @@ const doAuthorize = (autoApprove, checkedScopes, uncheckedScopes) => {
const formatScope = (scope) => {
// scope 便
// demo "system_oauth2_scope" scope
// TODO
return t(`login.sso.${scope}`)
}
const route = useRoute()
@ -146,7 +144,6 @@ const init = () => {
//
getAuthorize(params.clientId).then((res) => {
console.log(res)
client.value = res.client
// scope
let scopes
@ -173,5 +170,18 @@ const init = () => {
}
})
}
// =======SSO======
const { currentRoute } = useRouter()
//
watch(
() => currentRoute.value,
(route: RouteLocationNormalizedLoaded) => {
if (route.name === 'SSOLogin') {
setLoginState(LoginStateEnum.SSO)
init()
}
},
{ immediate: true }
)
init()
</script>