From 1103f8ff398343222ec37708b4908e13797c7080 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 7 Apr 2023 01:45:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0SSO=E5=8D=95=E7=82=B9?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 2d019f1bf96b94e879b79ad83e13c5eea12a94bd) --- src/api/login/index.ts | 44 +++++ src/config/axios/service.ts | 4 +- src/locales/zh-CN.ts | 7 + src/router/index.ts | 4 +- src/router/modules/remaining.ts | 10 + src/views/Login/Login.vue | 20 +- src/views/Login/components/LoginForm.vue | 11 +- src/views/Login/components/LoginFormTitle.vue | 3 +- src/views/Login/components/SSOLogin.vue | 177 ++++++++++++++++++ src/views/Login/components/index.ts | 3 +- src/views/Login/components/useLogin.ts | 3 +- 11 files changed, 276 insertions(+), 10 deletions(-) create mode 100644 src/views/Login/components/SSOLogin.vue diff --git a/src/api/login/index.ts b/src/api/login/index.ts index 0c895663..bc60e8c9 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -1,16 +1,19 @@ import request from '@/config/axios' import { getRefreshToken } from '@/utils/auth' import type { UserLoginVO } from './types' +import { service } from '@/config/axios/service' export interface CodeImgResult { captchaOnOff: boolean img: string uuid: string } + export interface SmsCodeVO { mobile: string scene: number } + export interface SmsLoginVO { mobile: string code: string @@ -71,3 +74,44 @@ export const getCodeApi = (data) => { export const reqCheckApi = (data) => { return request.postOriginal({ url: 'system/captcha/check', data }) } + +// ========== OAUTH 2.0 相关 ========== + +export const getAuthorize = (clientId) => { + return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId }) +} + +export function authorize( + responseType: string, + clientId: string, + redirectUri: string, + state: string, + autoApprove: boolean, + checkedScopes: any, + uncheckedScopes: any +) { + // 构建 scopes + const scopes = {} + for (const scope of checkedScopes) { + scopes[scope] = true + } + for (const scope of uncheckedScopes) { + scopes[scope] = false + } + // 发起请求 + return service({ + url: '/system/oauth2/authorize', + headers: { + 'Content-type': 'application/x-www-form-urlencoded' + }, + params: { + response_type: responseType, + client_id: clientId, + redirect_uri: redirectUri, + state: state, + auto_approve: autoApprove, + scope: JSON.stringify(scopes) + }, + method: 'post' + }) +} diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index fb205a6b..d37dfb06 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -1,8 +1,8 @@ import axios, { + AxiosError, AxiosInstance, AxiosRequestHeaders, AxiosResponse, - AxiosError, InternalAxiosRequestConfig } from 'axios' @@ -230,7 +230,7 @@ const handleAuthorized = () => { wsCache.clear() removeToken() isRelogin.show = false - window.location.href = import.meta.env.VITE_BASE_PATH + window.location.href = '/login?redirect=/sso?' + window.location.href.split('?')[1] }) } return Promise.reject(t('sys.api.timeoutMessage')) diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 6f46f1ab..e139fe62 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -129,6 +129,12 @@ export default { btnMobile: '手机登录', btnQRCode: '二维码登录', qrcode: '扫描二维码登录', + sso: { + user: { + read: '访问你的个人信息', + write: '修改你的个人信息' + } + }, btnRegister: '注册', SmsSendMsg: '验证码已发送' }, @@ -353,6 +359,7 @@ export default { login: { backSignIn: '返回', signInFormTitle: '登录', + ssoFormTitle: '三方授权', mobileSignInFormTitle: '手机登录', qrSignInFormTitle: '二维码登录', signUpFormTitle: '注册', diff --git a/src/router/index.ts b/src/router/index.ts index 02d913f8..8f66ca31 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,11 +1,11 @@ import type { App } from 'vue' import type { RouteRecordRaw } from 'vue-router' -import { createRouter, createWebHashHistory } from 'vue-router' +import { createRouter, createWebHistory } from 'vue-router' import remainingRouter from './modules/remaining' // 创建路由实例 const router = createRouter({ - history: createWebHashHistory(), // createWebHashHistory URL带#,createWebHistory URL不带# + history: createWebHistory(), // createWebHashHistory URL带#,createWebHistory URL不带# strict: true, routes: remainingRouter as RouteRecordRaw[], scrollBehavior: () => ({ left: 0, top: 0 }) diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 9bf298db..288db9b6 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -185,6 +185,16 @@ const remainingRouter: AppRouteRecordRaw[] = [ noTagsView: true } }, + { + path: '/sso', + component: () => import('@/views/Login/Login.vue'), + name: 'SSOLogin', + meta: { + hidden: true, + title: t('router.login'), + noTagsView: true + } + }, { path: '/403', component: () => import('@/views/Error/403.vue'), diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index a513b0ca..4bd9ff90 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -52,6 +52,11 @@ + + @@ -65,12 +70,25 @@ import { useDesign } from '@/hooks/web/useDesign' import { useAppStore } from '@/store/modules/app' import { ThemeSwitch } from '@/layout/components/ThemeSwitch' import { LocaleDropdown } from '@/layout/components/LocaleDropdown' -import { LoginForm, MobileForm, RegisterForm, QrCodeForm } from './components' + +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 } +)