From eeae0af978e4e38841b3c9a09b09a716ac2b8bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cwuzhen=E2=80=9D?= Date: Mon, 26 Oct 2026 15:50:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E4=BC=9A=E8=AF=9D=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E6=97=B6=E5=BC=BA=E5=88=B6=E6=B8=85=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=20token=EF=BC=8C=E9=81=BF=E5=85=8D=E5=8D=A1=E6=AD=BB=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=BF=9B=E5=85=A5=E7=99=BB=E5=BD=95=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 坏 JWT 会导致 logout 接口失败,原先 removeToken 执行不到,且 getInfo 失败后跳到 / 形成死循环。 Confidence: high Scope-risk: narrow Co-authored-by: Cursor --- web/src/permission.ts | 5 +++-- web/src/store/modules/user.ts | 17 +++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/web/src/permission.ts b/web/src/permission.ts index c5fbb283..5970cfe9 100644 --- a/web/src/permission.ts +++ b/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(); diff --git a/web/src/store/modules/user.ts b/web/src/store/modules/user.ts index 0fb0965a..2eb3657f 100644 --- a/web/src/store/modules/user.ts +++ b/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 => { - 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) => {