diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index df7dd70..be4527c 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -101,7 +101,10 @@ addEventListener('fetch', function (event) { // Opening the DevTools triggers the "only-if-cached" request // that cannot be handled by the worker. Bypass such requests. - if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { + if ( + event.request.cache === 'only-if-cached' && + event.request.mode !== 'same-origin' + ) { return } @@ -153,7 +156,7 @@ async function handleRequest(event, requestId) { }, }, }, - responseClone.body ? [serializedRequest.body, responseClone.body] : [] + responseClone.body ? [serializedRequest.body, responseClone.body] : [], ) } @@ -217,7 +220,9 @@ async function getResponse(event, client, requestId) { const acceptHeader = headers.get('accept') if (acceptHeader) { const values = acceptHeader.split(',').map((value) => value.trim()) - const filteredValues = values.filter((value) => value !== 'msw/passthrough') + const filteredValues = values.filter( + (value) => value !== 'msw/passthrough', + ) if (filteredValues.length > 0) { headers.set('accept', filteredValues.join(', ')) @@ -253,7 +258,7 @@ async function getResponse(event, client, requestId) { ...serializedRequest, }, }, - [serializedRequest.body] + [serializedRequest.body], ) switch (clientMessage.type) { @@ -287,7 +292,10 @@ function sendToClient(client, message, transferrables = []) { resolve(event.data) } - client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]) + client.postMessage(message, [ + channel.port2, + ...transferrables.filter(Boolean), + ]) }) } diff --git a/src/hooks/auth.ts b/src/hooks/auth.ts index b019152..0b96f55 100644 --- a/src/hooks/auth.ts +++ b/src/hooks/auth.ts @@ -52,12 +52,16 @@ export function useLogout() { toast.success('Log out successful!'); // 清除所有查询缓存 queryClient.clear(); + // 清除 Next.js 路由缓存,确保中间件能读取到最新的 cookie 状态 + router.refresh(); router.push('/'); }, onError: (error: ApiError) => { // 即使登出接口失败,也要清除本地token tokenManager.removeToken(); queryClient.clear(); + // 清除 Next.js 路由缓存,确保中间件能读取到最新的 cookie 状态 + router.refresh(); // 跳转到登录页 router.push('/'); }, diff --git a/src/lib/auth/token.ts b/src/lib/auth/token.ts index d972ce4..a660777 100644 --- a/src/lib/auth/token.ts +++ b/src/lib/auth/token.ts @@ -10,8 +10,8 @@ function generateDeviceId(): string { const browserInfo = typeof window !== 'undefined' ? `${window.navigator.userAgent}${window.screen.width}${window.screen.height}` - .replace(/\s/g, '') - .substring(0, 10) + .replace(/\s/g, '') + .substring(0, 10) : 'server'; return `did_${timestamp}_${randomStr}_${browserInfo}`.toLowerCase(); @@ -107,7 +107,12 @@ export const tokenManager = { removeToken: (): void => { if (typeof window !== 'undefined') { console.log('remove token'); - Cookies.remove(TOKEN_COOKIE_NAME); + // 删除cookie时需要指定与设置时相同的选项 + Cookies.remove(TOKEN_COOKIE_NAME, { + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + path: '/', + }); // 同时清除可能存在的localStorage token window.localStorage.removeItem('token'); // 注意:这里不清除设备ID @@ -117,8 +122,13 @@ export const tokenManager = { // 清除所有数据(包括设备ID) clearAll: (): void => { if (typeof window !== 'undefined') { - Cookies.remove(TOKEN_COOKIE_NAME); - Cookies.remove(DEVICE_ID_COOKIE_NAME); + const cookieOptions = { + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax' as const, + path: '/', + }; + Cookies.remove(TOKEN_COOKIE_NAME, cookieOptions); + Cookies.remove(DEVICE_ID_COOKIE_NAME, cookieOptions); window.localStorage.removeItem('token'); } },