Browse Source

fix(web): 会话失效时强制清本地 token,避免卡死无法进入登录页

坏 JWT 会导致 logout 接口失败,原先 removeToken 执行不到,且 getInfo 失败后跳到 / 形成死循环。

Confidence: high
Scope-risk: narrow
Co-authored-by: Cursor <cursoragent@cursor.com>
“wuzhen” 4 days ago
parent
commit
eeae0af978
2 changed files with 14 additions and 8 deletions
  1. 3 2
      web/src/permission.ts
  2. 11 6
      web/src/store/modules/user.ts

+ 3 - 2
web/src/permission.ts

@@ -37,6 +37,7 @@ router.beforeEach(async (to, from, next) => {
     to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
     /* has token*/
     if (to.path === '/login') {
+      // 已有 token 时先进首页;若会话已失效,下面 getInfo 失败会清 token 并回登录页
       next({ path: '/' });
       NProgress.done();
     } else if (isWhiteList(to.path)) {
@@ -47,9 +48,9 @@ router.beforeEach(async (to, from, next) => {
         // 判断当前用户是否已拉取完user_info信息
         const [err] = await tos(useUserStore().getInfo());
         if (err) {
+          isRelogin.show = false;
           await useUserStore().logout();
-          // ElMessage.error(err.message || '获取用户信息失败');
-          next({ path: '/' });
+          next(`/login?redirect=${encodeURIComponent(to.fullPath || '/')}`);
         } else {
           isRelogin.show = false;
           const accessRoutes = await usePermissionStore().generateRoutes();

+ 11 - 6
web/src/store/modules/user.ts

@@ -65,13 +65,18 @@ export const useUserStore = defineStore('user', () => {
     return Promise.reject(err);
   };
 
-  // 注销
+  // 注销(后端失败也不能挡住清本地 token,否则坏 JWT 会导致永远进不了登录页)
   const logout = async (): Promise<void> => {
-    await logoutApi();
-    token.value = '';
-    roles.value = [];
-    permissions.value = [];
-    removeToken();
+    try {
+      await logoutApi();
+    } catch {
+      // ignore:token 已失效/签名无效时服务端注销也会失败
+    } finally {
+      token.value = '';
+      roles.value = [];
+      permissions.value = [];
+      removeToken();
+    }
   };
 
   const setAvatar = (value: string) => {