基于JWT双Token机制:解决令牌过期与实现无感续期 作者:马育民 • 2026-07-26 23:18 • 阅读:10001 # 单Token的缺点 时效设短→频繁掉线;时效设长→泄露风险巨大;很难主动失效。适合小型内部系统。 ### 解决 使用 **双Token**,大中型Web、APP、小程序、开放平台标准方案。 # 两个令牌分工 | 令牌 | 有效期推荐 | 作用 | 使用场景 | |------|------------|------|----------| | **Access Token(访问令牌)** | 15min~60min(短时效) | 业务接口鉴权 | 每次请求放在请求头:`Authorization: Bearer xxx` | | **Refresh Token(刷新令牌)** | 7~30天(长时效) | **只用来换新Access Token** | 仅调用 `/refresh` 刷新接口,**不参与普通业务请求** | > 核心思想:**鉴权凭证短命,续期凭证长效**。 # 基础版-执行流程 1. 用户账号密码登录,校验通过 → 后端一次性返回 `accessToken` + `refreshToken` 2. 前端本地保存双token;所有业务请求自动携带 accessToken 3. accessToken过期,后端返回 **401 Unauthorized** 4. 前端拦截401,暂停后续请求,携带 refreshToken 请求刷新接口 5. 后端校验 refreshToken: - ✅ 有效:下发**新accessToken**(企业级常用:同时下发新refreshToken,旧refreshToken作废 → **令牌轮换**) - ❌ 失效:清空登录态,跳转登录页 6. 前端更新本地token,重新发起之前失败的请求 > 整个刷新过程用户无感知,俗称**无感刷新** ### 登录时序图 [](https://www.malaoshi.top/upload/0/0/1GW3ke3dsCkj.png) ### 发起业务请求时序图 [](https://www.malaoshi.top/upload/0/0/1GW3keFPHFMa.png) # 高级版(补充) - **基础版:**只解决「token过期无感登录」的核心流程,静态RefreshToken、仅刷新Access、无并发控制、无失效管控 - **高级版:**解决**令牌泄露、并发冲突、强制下线、跨设备管控、前端安全、异常容错**等线上风险。 ### 1. RefreshToken 安全增强(令牌轮换机制) 1. 每次刷新成功,同时下发**新Access Token + 新Refresh Token** 2. 旧Refresh Token 立刻标记失效,存入黑名单(Redis) 3. 限制:同一个RefreshToken只允许使用一次,防止窃取后被反复利用 4. 可选:设置刷新窗口期,规避网络延迟导致新旧RT并行问题 ### 2. 前端并发请求问题处理 1. **全局刷新锁**:多个业务请求同时401时,只发起一次刷新请求 2. 请求队列缓存:刷新期间新增业务请求放入队列,刷新完成统一重试 3. 刷新进行中,拒绝重复调用刷新接口,避免大量重复刷新 ### 3. RefreshToken 精细化管控(后端) 1. RT绑定信息:绑定**用户ID、设备标识、客户端类型、IP(可选)** 2. 支持单设备下线、全部设备批量踢人(后台强制登出) 3. RT持久化存储(Redis/数据库),不再依赖纯无状态JWT 4. RT过期自动清理,定期清理黑名单失效数据 ### 4. 安全防御策略 1. 刷新接口风控:短时间多次刷新失败,临时封禁IP/客户端 2. 传输规范:RefreshToken存放于**HttpOnly + Secure Cookie**,抵御XSS窃取 3. AccessToken可放内存,不长期存在localStorage 4. 校验刷新请求:仅允许刷新接口使用RT,普通业务接口拒绝携带RT ### 5. 边界异常场景处理 1. 刷新接口调用途中网络中断(原子性保证,防止新旧令牌混乱) 2. 新旧RefreshToken交替的兼容窗口期 3. 浏览器多标签页登录状态同步(标签A刷新token,标签B感知状态) 4. 用户主动登出:删除当前设备RT、加入黑名单 ### 6. 可拓展策略(可选) 1. 滑动过期:用户持续活跃时,适度延长RefreshToken有效期 2. 异地登录提醒、陌生设备拦截 3. Token载荷轻量化,敏感信息不存入JWT,由后端查询 # 优势 1. **安全性更高** Access Token短期有效,即使被抓包/XSS窃取,攻击者可用时间很短; Refresh Token传输频次极低,可做严格管控(绑定设备、IP、存在HttpOnly Cookie)。 2. **体验更好** 不用频繁弹窗登录,后台静默续期。 3. **支持主动下线** Refresh Token建议存入Redis/数据库(**不能只用纯JWT**),管理员封号、用户主动登出时,后端直接删除refreshToken,立刻失效登录。 # 缺点 & 坑点 1. 前端复杂度上升: 需要处理**并发请求同时触发刷新**(必须加锁、请求队列,防止多次调用刷新接口) 2. 后端需要存储Refresh Token,不再是纯无状态JWT; 3. 存储安全问题: - accessToken 存在 localStorage 易受XSS; - refreshToken 优先放到 **HttpOnly Cookie** 防止前端脚本窃取。 # 两种刷新策略(基础 VS 高级) 1. **静态RefreshToken(简易版)** 每次只更新accessToken,refreshToken一直不变 风险:refreshToken一旦泄露,可以无限续期accessToken 2. **Refresh Token 轮换(生产推荐)** 每次刷新都生成全新refreshToken,旧RT立刻拉黑失效;大幅降低长期泄露风险。 # 总结 双Token由短期Access Token和长期Refresh Token组成。Access Token用于日常接口鉴权,过期后前端使用Refresh Token调用刷新接口换取新令牌,实现无感登录。Access Token缩短有效期控制泄露风险;Refresh Token服务端存储,可以实现强制下线,平衡安全性与用户体验。 原文出处:http://malaoshi.top/show_1GW3kUhC32BW.html