Skip to content

Commit 6f450ff

Browse files
CodFrmclaude
andcommitted
🔄 Token 自动刷新:页面加载时自动续期登录 token
在 UserContext 中添加 token 自动刷新逻辑,用户登录状态下每 3 天 自动调用 refresh-token 接口续期,避免 7 天过期后需要重新登录。 通过 localStorage 记录上次刷新时间,减少不必要的请求。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7cf214a commit 6f450ff

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

src/contexts/UserContext.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
'use client';
22

3-
import React, { createContext, useCallback, useContext, useMemo } from 'react';
3+
import React, {
4+
createContext,
5+
useCallback,
6+
useContext,
7+
useEffect,
8+
useMemo,
9+
} from 'react';
410
import { userService } from '@/lib/api';
511
import type { UserInfo } from '@/lib/api/services/user';
612

@@ -34,6 +40,24 @@ export function UserProvider({
3440
}
3541
}, []);
3642

43+
useEffect(() => {
44+
if (!user) return;
45+
// 距上次刷新不足 3 天则跳过,避免每次加载都请求
46+
const REFRESH_INTERVAL = 3 * 24 * 60 * 60 * 1000; // 3 天
47+
const STORAGE_KEY = 'token_last_refresh';
48+
const last = Number(localStorage.getItem(STORAGE_KEY) || '0');
49+
if (Date.now() - last < REFRESH_INTERVAL) return;
50+
51+
userService
52+
.refreshToken()
53+
.then(() => {
54+
localStorage.setItem(STORAGE_KEY, String(Date.now()));
55+
})
56+
.catch(() => {
57+
// 刷新失败静默忽略,不影响用户体验
58+
});
59+
}, []);
60+
3761
const value = useMemo<UserContextType>(
3862
() => ({
3963
user,

src/lib/api/services/user.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ export class UserService {
197197
return apiClient.put<Webhook>(`${this.basePath}/webhook`);
198198
}
199199

200+
/**
201+
* 刷新登录 token(fire-and-forget)
202+
* 后端会判断是否需要刷新(超过3天才会真正刷新)
203+
*/
204+
async refreshToken() {
205+
return apiClient.post<void>(`${this.basePath}/refresh-token`);
206+
}
207+
200208
/**
201209
* 设置用户通知配置
202210
* @param notify 通知配置对象

0 commit comments

Comments
 (0)