Browse Source

fix(auth):优化令牌失效处理逻辑

- 使用 tokenStore.clearToken() 清除令牌- 添加 try/catch 兜底 updateToken('')
- 会话存储标记 NEED_LOGIN_MODAL 控制登录弹窗显示- 延迟显示令牌失效提示消息
- 修复 computed ref 类型 token 获取方式
- main.ts 中根据会话标记控制登录弹窗显示
- token store 添加 clearToken 方法
- 用户信息清空时同步清除令牌
- 获取用户信息失败时清除令牌并提示重新登录
panqiuyao 2 months ago
parent
commit
652d6ec663

+ 11 - 0
frontend/src/main.ts

@@ -7,6 +7,7 @@ import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 import { lissenLog, log } from './utils/log'
+import useUserInfo from './stores/modules/user'
 
 const app = createApp(App)
 app.use(ElementPlus)
@@ -21,3 +22,13 @@ lissenLog(app)
 log(router)
 
 app.mount('#app')
+
+// 刷新后根据会话标记显示登录弹窗
+try {
+    const flag = sessionStorage.getItem('NEED_LOGIN_MODAL')
+    if (flag) {
+        const userStore = useUserInfo()
+        userStore.updateLoginShow(true)
+        sessionStorage.removeItem('NEED_LOGIN_MODAL')
+    }
+} catch {}

+ 5 - 1
frontend/src/stores/modules/token.ts

@@ -9,10 +9,14 @@ export const tokenInfo = defineStore('tokenInfo',()=>{
   const updateToken = (data:string)=>{
     token.value = data
   }
+  const clearToken = () => {
+    token.value = ''
+  }
   return {
     token,
     getToken,
-    updateToken
+    updateToken,
+    clearToken
   }
 },{
   persist:true,

+ 10 - 2
frontend/src/stores/modules/user.ts

@@ -84,7 +84,11 @@ export const useUserInfo = defineStore('userInfo', () => {
       }
 
       // 清空用户信息
-      await updateToken(''); // 更新登录令牌
+      try {
+        tokenInfoStore.clearToken()
+      } catch (e) {
+        await updateToken('')
+      }
       await updateUserInfo({});
 
       // 跳转到首页
@@ -115,7 +119,11 @@ export const useUserInfo = defineStore('userInfo', () => {
       }); // 调用获取用户信息接口
       const { data } = res;
       if (!data) {
-        updateToken(''); // 如果没有数据,清空令牌
+        try {
+          tokenInfoStore.clearToken()
+        } catch (e) {
+          updateToken('')
+        }
         throw new Error('请重新登录!');
       }
       updateUserInfo(data); // 更新用户信息

+ 21 - 13
frontend/src/utils/http.ts

@@ -38,19 +38,23 @@ async function handleTokenExpiry() {
 
         // 清空用户信息
         const useUserInfoStore = useUserInfo();
-        await useUserInfoStore.updateToken('');
+        try {
+            const tokenStore = tokenInfo();
+            tokenStore.clearToken();
+        } catch (e) {
+            await useUserInfoStore.updateToken('');
+        }
         await useUserInfoStore.updateUserInfo({});
 
-        // 跳转到首页
+        // 跳转到首页(在会话存储中标记需要显示登录框)
         try {
+            sessionStorage.setItem('NEED_LOGIN_MODAL', '1');
             window.location.href = '/'
             console.log('Token失效:已跳转到首页');
         } catch (error) {
             console.error('Token失效:跳转到首页失败:', error);
         }
-
-        // 显示登录弹窗
-        useUserInfoStore.updateLoginShow(true);
+        // 刷新后在 main.ts 中处理显示登录弹窗
     } catch (error) {
         console.error('Token失效处理失败:', error);
     }
@@ -84,9 +88,10 @@ service.interceptors.request.use(
 
         // 在发送请求之前做些什么,例如添加 token
         const tokenInfoStore = tokenInfo();
-        const token = tokenInfoStore.getToken; // 使用 getToken() 获取 token
-        if (token) {
-            config.headers['Authorization'] = `Bearer ${token}`;
+        const token = tokenInfoStore.getToken; // computed ref
+        const tokenValue = typeof token === 'object' && token !== null && 'value' in token ? (token as any).value : token as any;
+        if (tokenValue) {
+            config.headers['Authorization'] = `Bearer ${tokenValue}`;
         }
 
         // 如果配置中启用了加载动画,则显示加载动画
@@ -127,11 +132,14 @@ service.interceptors.response.use(
         if (res.code !== 0) {
             switch (res.code) {
                 case 401:
-                    Message({
-                        message: '登录状态已失效,请重新登录',
-                        type: 'error',
-                        duration: 3 * 1000,
-                    });
+                    setTimeout(()=>{
+
+                        Message({
+                            message: '登录状态已失效,请重新登录',
+                            type: 'error',
+                            duration: 3 * 1000,
+                        });
+                    },1000)
                     // 处理token失效
                     handleTokenExpiry();
                     break;