From e754feeb68eb68e914fccfbb191c171dcdf05c48 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 28 Jan 2026 18:51:17 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=B3=E8=BD=AC?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=8D=E7=99=BB=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TokenRefreshManager.tsx | 38 +++++++++++++++++++++++--- src/lib/auth.ts | 16 +++++++++++ src/lib/db.client.ts | 4 ++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/components/TokenRefreshManager.tsx b/src/components/TokenRefreshManager.tsx index 375171e..21f3cd2 100644 --- a/src/components/TokenRefreshManager.tsx +++ b/src/components/TokenRefreshManager.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react'; -import { getAuthInfoFromBrowserCookie } from '@/lib/auth'; +import { getAuthInfoFromBrowserCookie, clearAuthCookie } from '@/lib/auth'; /** * Token 自动刷新管理器 @@ -50,8 +50,18 @@ export function TokenRefreshManager() { } else { console.error('[Token] Refresh failed:', response.status); - // 刷新失败,跳转登录 + // 刷新失败,先登出再跳转登录 if (response.status === 401 || response.status === 403) { + try { + await window.fetch('/api/logout', { + method: 'POST', + credentials: 'include', + }); + } catch (error) { + console.error('[Token] Logout error:', error); + // 登出失败时清除前端cookie + clearAuthCookie(); + } window.location.href = `/login?redirect=${encodeURIComponent(window.location.pathname + window.location.search)}`; } return false; @@ -80,7 +90,17 @@ export function TokenRefreshManager() { // Refresh Token 已过期 if (now >= authInfo.refreshExpires) { console.log('[Token] Refresh token expired, redirecting to login'); - window.location.href = `/login?redirect=${encodeURIComponent(window.location.pathname + window.location.search)}`; + // 先登出再跳转登录 + window.fetch('/api/logout', { + method: 'POST', + credentials: 'include', + }).catch(error => { + console.error('[Token] Logout error:', error); + // 登出失败时清除前端cookie + clearAuthCookie(); + }).finally(() => { + window.location.href = `/login?redirect=${encodeURIComponent(window.location.pathname + window.location.search)}`; + }); return false; } @@ -132,9 +152,19 @@ export function TokenRefreshManager() { // 刷新成功,重试原请求(仅此一次) response = await originalFetch(input, init); - // 如果重试后仍然是 401,说明有问题,跳转登录 + // 如果重试后仍然是 401,说明有问题,先登出再跳转登录 if (response.status === 401) { console.error('[Token] Still 401 after refresh, redirecting to login'); + try { + await originalFetch('/api/logout', { + method: 'POST', + credentials: 'include', + }); + } catch (error) { + console.error('[Token] Logout error:', error); + // 登出失败时清除前端cookie + clearAuthCookie(); + } window.location.href = `/login?redirect=${encodeURIComponent(window.location.pathname + window.location.search)}`; } } diff --git a/src/lib/auth.ts b/src/lib/auth.ts index f4b31b9..aff1762 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -111,3 +111,19 @@ export function getAuthInfoFromBrowserCookie(): AuthInfo | null { return null; } } + +// 清除浏览器中的认证cookie (客户端使用) +export function clearAuthCookie(): void { + if (typeof window === 'undefined') { + return; + } + + try { + // 清除 auth cookie,设置过期时间为过去 + document.cookie = 'auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax'; + // 如果有其他域名或路径的cookie,也尝试清除 + document.cookie = 'auth=; path=/; domain=' + window.location.hostname + '; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax'; + } catch (error) { + console.error('[Auth] Failed to clear cookie:', error); + } +} diff --git a/src/lib/db.client.ts b/src/lib/db.client.ts index 3703572..bd2b532 100644 --- a/src/lib/db.client.ts +++ b/src/lib/db.client.ts @@ -14,7 +14,7 @@ * 如后续需要在客户端读取收藏等其它数据,可按同样方式在此文件中补充实现。 */ -import { getAuthInfoFromBrowserCookie } from './auth'; +import { getAuthInfoFromBrowserCookie, clearAuthCookie } from './auth'; import { DanmakuFilterConfig, EpisodeFilterConfig,SkipConfig } from './types'; // 全局错误触发函数 @@ -561,6 +561,8 @@ async function fetchWithAuth( }); } catch (error) { console.error('注销请求失败:', error); + // 登出失败时清除前端cookie + clearAuthCookie(); } const currentUrl = window.location.pathname + window.location.search; const loginUrl = new URL('/login', window.location.origin); From d778c988bddcaf85654a7ae8f558c4ed61bf52f0 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 28 Jan 2026 19:42:13 +0800 Subject: [PATCH 2/2] 21013 --- CHANGELOG | 4 ++++ VERSION.txt | 2 +- src/lib/changelog.ts | 10 ++++++++++ src/lib/version.ts | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d7bc1ec..e850c4f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +## [210.1.3] - 2026-01-28 +### Fixed +- 修复跳转登录不登出 + ## [210.1.2] - 2026-01-27 ### Fixed - 修复刷新token失效无限重定向 diff --git a/VERSION.txt b/VERSION.txt index bdea846..4a9fffe 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,2 +1,2 @@ -210.1.2 +210.1.3 diff --git a/src/lib/changelog.ts b/src/lib/changelog.ts index 977d26e..95893f7 100644 --- a/src/lib/changelog.ts +++ b/src/lib/changelog.ts @@ -11,6 +11,16 @@ export interface ChangelogEntry { export const changelog: ChangelogEntry[] = [ { + version: '210.1.3', + date: '2026-01-28', + added: [ + ], + changed: [ + ], + fixed: [ + "修复跳转登录不登出" + ] + },{ version: '210.1.2', date: '2026-01-27', added: [ diff --git a/src/lib/version.ts b/src/lib/version.ts index c8fef0c..df2c6d2 100644 --- a/src/lib/version.ts +++ b/src/lib/version.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ -const CURRENT_VERSION = '210.1.2'; +const CURRENT_VERSION = '210.1.3'; // 导出当前版本号供其他地方使用 export { CURRENT_VERSION };