前端无感刷新Token
在现代 Web 应用中,身份验证(Authentication)和权限控制(Authorization)是保障安全的核心机制。通常,前端登录成功后会拿到一个 access_token(访问令牌)用于后续请求。但为了安全,这个 access_token 的有效期往往较短,比如 15 分钟或 1 小时。如果不做处理,Token 过期后用户就需要重新登录,这会导致用户体验变差。为了解决这个问题,我们引入了“无感刷新 Token”机制,即在不打断用户操作的前提下,悄悄完成 Token 的续期,让经常使用的用户察觉不到 Token 的生命周期。
是什么
无感刷新 Token(Silent Token Refresh),是指在不弹窗、不跳转的情况下,在 Token 即将过期或请求返回 401 时自动进行 Token 刷新,并重新发起之前失败的请求。
主要目标:
- 保障用户登录状态持续有效
- 避免频繁弹窗提示重新登录
- 提升用户体验和系统稳定性
为什么不直接延长 Access Token 有效期:
直接把 Token 设置成一天甚至一周不过期,会引发两个问题:
- 安全性降低:Access Token 通常是无状态的 JWT,携带用户身份信息,若被窃取,在有效期内都可被滥用。
- 不可控注销:你无法在服务端主动让一个 JWT 失效,除非维护一个黑名单(引入了状态和复杂性)。
因此,最佳实践是:
- 使用短效的
access_token(如 15 分钟) - 配合一个长效的
refresh_token(如 7 天)进行续期
基本流程
通常,刷新 Token 的接口只发送
refresh_token,服务端验证后返回新的 Token 对。
1 | 用户登录 |
方案设计(推荐)
接口约定
登录接口返回:
1
2
3
4
5{
"access_token": "xxx",
"refresh_token": "yyy",
"expires_in": 900
}刷新 Token 接口(POST
/auth/refresh): 请求体/请求头携带refresh_token成功返回新的 token 对,失败返回 401,提示客户端清除状态并跳转登录。
前端设计思路:
- 拦截请求和响应,统一处理 Token 添加和刷新
- 用 Axios 拦截器在 401 时触发刷新逻辑
- 刷新成功后重发原请求
- 使用队列或锁避免并发刷新
前端实现(示例)
以下以 Axios + React 为例
Token 存储
| 类型 | 存储位置 | 说明 |
|---|---|---|
access_token |
内存 / Cookie | 避免长久保存,防 XSS |
refresh_token |
HttpOnly Cookie | 后端设置,防止 JS 读取(推荐) |
Axios 拦截器
1 | import axios from 'axios' |
在代码实现时需注意:
避免频繁刷新
在多个请求同时返回 401 时,如果不加锁会导致多个刷新请求发出。可用
isRefreshing和队列来避免。刷新接口失败处理
建议跳转登录页,并清空所有 Token 数据。可以使用全局状态管理(如 Redux/Zustand)清空登录状态。
刷新策略选择
除了在 401 时刷新,也可以提前几分钟自动刷新,可搭配定时器 +
expires_in实现。
前端无感刷新Token