From 35433b47522314423ddd0111663c0e453e4615d8 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 17 Jun 2025 20:26:20 +0800 Subject: [PATCH] feat: chat auth (#3285) --- ui/src/api/chat/chat.ts | 58 ++++---- ui/src/request/chat/index.ts | 13 -- ui/src/router/chat/index.ts | 54 ++++++-- ui/src/stores/modules/chat-user.ts | 22 ++- ui/src/views/chat/user-login/index.vue | 183 ++++++------------------- 5 files changed, 132 insertions(+), 198 deletions(-) diff --git a/ui/src/api/chat/chat.ts b/ui/src/api/chat/chat.ts index 32d9dcf2b..de7d4bbb8 100644 --- a/ui/src/api/chat/chat.ts +++ b/ui/src/api/chat/chat.ts @@ -1,4 +1,4 @@ -import {Result} from '@/request/Result' +import { Result } from '@/request/Result' import { get, post, @@ -9,16 +9,16 @@ import { download, exportFile, } from '@/request/chat/index' -import {type ChatProfile} from '@/api/type/chat' -import {type Ref} from 'vue' +import { type ChatProfile } from '@/api/type/chat' +import { type Ref } from 'vue' import useStore from '@/stores' -import type {LoginRequest} from "@/api/type/user.ts"; +import type { LoginRequest } from '@/api/type/user' -const prefix: any = {_value: '/workspace/'} +const prefix: any = { _value: '/workspace/' } Object.defineProperty(prefix, 'value', { get: function () { - const {user} = useStore() + const { user } = useStore() return this._value + user.getWorkspaceId() + '/application' }, }) @@ -31,7 +31,6 @@ Object.defineProperty(prefix, 'value', { */ const open: (loading?: Ref) => Promise> = (loading) => { return get('/open', {}, loading) - } /** * 对话 @@ -46,7 +45,7 @@ const chatProfile: (assessToken: string, loading?: Ref) => Promise { - return get('/profile', {access_token: assessToken}, loading) + return get('/profile', { access_token: assessToken }, loading) } /** * 匿名认证 @@ -58,7 +57,7 @@ const anonymousAuthentication: ( assessToken: string, loading?: Ref, ) => Promise> = (assessToken, loading) => { - return post('/auth/anonymous', {access_token: assessToken}, {}, loading) + return post('/auth/anonymous', { access_token: assessToken }, {}, loading) } /** * 获取应用相关信息 @@ -69,30 +68,28 @@ const applicationProfile: (loading?: Ref) => Promise> = (lo return get('/application/profile', {}, loading) } - /** * 登录 * @param request 登录接口请求表单 * @param loading 接口加载器 * @returns 认证数据 */ -const login: (accessToken: string, request: LoginRequest, loading?: Ref) => Promise> = ( +const login: ( accessToken: string, - request, - loading, -) => { + request: LoginRequest, + loading?: Ref, +) => Promise> = (accessToken: string, request, loading) => { return post('/auth/login/' + accessToken, request, undefined, loading) } -const ldapLogin: (accessToken: string, request: LoginRequest, loading?: Ref) => Promise> = ( +const ldapLogin: ( accessToken: string, - request, - loading, -) => { + request: LoginRequest, + loading?: Ref, +) => Promise> = (accessToken: string, request, loading) => { return post('/auth/ldap/login/' + accessToken, request, undefined, loading) } - /** * 获取验证码 * @param loading 接口加载器 @@ -114,35 +111,38 @@ const getQrSource: (loading?: Ref) => Promise> = (loading) const getDingCallback: (code: string, loading?: Ref) => Promise> = ( code, - loading + loading, ) => { - return get('dingtalk', {code}, loading) + return get('dingtalk', { code }, loading) } const getDingOauth2Callback: (code: string, loading?: Ref) => Promise> = ( code, - loading + loading, ) => { - return get('dingtalk/oauth2', {code}, loading) + return get('dingtalk/oauth2', { code }, loading) } const getWecomCallback: (code: string, loading?: Ref) => Promise> = ( code, - loading + loading, ) => { - return get('wecom', {code}, loading) + return get('wecom', { code }, loading) } const getLarkCallback: (code: string, loading?: Ref) => Promise> = ( code, - loading + loading, ) => { - return get('lark/oauth2', {code}, loading) + return get('lark/oauth2', { code }, loading) } /** * 获取认证设置 */ -const getAuthSetting: (auth_type: string, loading?: Ref) => Promise> = (auth_type, loading) => { +const getAuthSetting: (auth_type: string, loading?: Ref) => Promise> = ( + auth_type, + loading, +) => { return get(`/chat_user/${auth_type}/detail`, undefined, loading) } export default { @@ -160,5 +160,5 @@ export default { getLarkCallback, getQrSource, ldapLogin, - getAuthSetting + getAuthSetting, } diff --git a/ui/src/request/chat/index.ts b/ui/src/request/chat/index.ts index 449803442..954b76fba 100644 --- a/ui/src/request/chat/index.ts +++ b/ui/src/request/chat/index.ts @@ -53,19 +53,6 @@ instance.interceptors.response.use( MsgError(err.message) console.error(err) } - if (err.response?.status === 401) { - const { chatUser } = useStore() - if (chatUser.accessToken) { - router.push({ name: 'login', params: { accessToken: chatUser.accessToken } }) - } else { - router.push('/404 ') - } - } - if (err.response?.status === 403 && !err.response.config.url.includes('chat/open')) { - MsgError( - err.response.data && err.response.data.message ? err.response.data.message : '没有权限访问', - ) - } return Promise.reject(err) }, ) diff --git a/ui/src/router/chat/index.ts b/ui/src/router/chat/index.ts index 288729172..c703c61d0 100644 --- a/ui/src/router/chat/index.ts +++ b/ui/src/router/chat/index.ts @@ -33,7 +33,15 @@ router.beforeEach( }) return } - const authentication = await chatUser.isAuthentication() + let authentication = false + try { + authentication = await chatUser.isAuthentication() + } catch (e: any) { + next({ + path: '/404', + }) + return + } const token = chatUser.getToken() if (authentication) { if (!token && to.name != 'login') { @@ -45,22 +53,46 @@ router.beforeEach( }) return } else { - next() - return + if (to.name == 'login') { + next() + return + } else { + try { + await chatUser.applicationProfile() + } catch (e: any) { + if (e.response?.status === 401) { + next({ + name: 'login', + params: { + accessToken: to.params.accessToken, + }, + }) + } + return + } + next() + return + } } } else { await chatUser.anonymousAuthentication() } if (!chatUser.application) { - await chatUser.applicationProfile() - } - // 判断是否有菜单权限 - if (to.meta.permission ? hasPermission(to.meta.permission as any, 'OR') : true) { - next() - } else { - // 如果没有权限则直接取404页面 - next('404') + try { + await chatUser.applicationProfile() + } catch (e: any) { + if (e.response?.status === 401) { + next({ + name: 'login', + params: { + accessToken: to.params.accessToken, + }, + }) + } + return + } } + next() }, ) router.afterEach(() => { diff --git a/ui/src/stores/modules/chat-user.ts b/ui/src/stores/modules/chat-user.ts index 8372698d7..3fd28b561 100644 --- a/ui/src/stores/modules/chat-user.ts +++ b/ui/src/stores/modules/chat-user.ts @@ -1,7 +1,8 @@ import { defineStore } from 'pinia' import ChatAPI from '@/api/chat/chat' import { type ChatProfile } from '@/api/type/chat' - +import type { LoginRequest } from '@/api/type/user' +import type { Ref } from 'vue' interface ChatUser { // 用户id id: string @@ -59,12 +60,29 @@ const useChatUserStore = defineStore('chat-user', { } return localStorage.getItem(`accessToken`) }, + setToken(token: string) { + this.token = token + sessionStorage.setItem(`${this.accessToken}-accessToken`, token) + localStorage.setItem(`${this.accessToken}-accessToken`, token) + }, /** *匿名认证 */ anonymousAuthentication() { return ChatAPI.anonymousAuthentication(this.accessToken as string).then((ok) => { - this.token = ok.data + this.setToken(ok.data) + return this.token + }) + }, + login(request: LoginRequest, loading?: Ref) { + return ChatAPI.login(this.accessToken as string, request, loading).then((ok) => { + this.setToken(ok.data.token) + return this.token + }) + }, + ldapLogin(request: LoginRequest, loading?: Ref) { + return ChatAPI.ldapLogin(this.accessToken as string, request, loading).then((ok) => { + this.setToken(ok.data.token) return this.token }) }, diff --git a/ui/src/views/chat/user-login/index.vue b/ui/src/views/chat/user-login/index.vue index 5d9cfebc4..7920faab8 100644 --- a/ui/src/views/chat/user-login/index.vue +++ b/ui/src/views/chat/user-login/index.vue @@ -2,7 +2,8 @@

- {{ loginMode == 'LOCAL' ? $t('views.login.title') : loginMode }}

+ {{ loginMode == 'LOCAL' ? $t('views.login.title') : loginMode }} +
- +