Spring Boot与Angular架构下如何实现JWT令牌自动刷新?
JWT自动刷新实现方案
因为你的JWT存储在httpOnly Cookie中,前端无法直接读取令牌内容,所以推荐优先用状态码触发的无感知刷新方案,整体实现分为前后端两部分:
一、后端补充适配逻辑(已有刷新逻辑只需调整少量配置)
- 给JWT校验拦截器加逻辑:当access token过期时,返回
401 Unauthorized状态码,同时在响应头添加自定义标识Token-Expired: true,用来区分「令牌过期」和「未登录/权限不足」的场景 - 刷新令牌接口放开access token校验限制,不需要携带有效access token即可访问
- 刷新逻辑校验通过后,通过
Set-Cookie响应头把新的access token写入httpOnly Cookie返回给前端,可按需同步刷新refresh token实现滑动有效期 - 可选配置:给过期的access token加5-10秒的容忍窗口,避免刷新过程中并发请求报错
二、前端实现逻辑
- 所有请求不需要手动处理令牌,浏览器会自动携带httpOnly Cookie发往后端
- 配置全局响应拦截器,统一处理接口返回结果:
- 当拦截到
401状态码,且响应头存在Token-Expired: true标识时,说明access token已过期,触发刷新流程 - 先加全局刷新锁,避免多个过期请求同时触发多次刷新:如果已经有正在进行的刷新请求,就把当前失败的请求暂存到请求队列,等刷新完成后再重放
- 没有正在进行的刷新请求时,发起调用后端刷新令牌的接口,浏览器会自动携带refresh token的httpOnly Cookie
- 刷新成功后,依次重放队列里所有暂存的失败请求,用户全程无感知
- 如果刷新请求也返回
401,说明refresh token也已失效,直接清空所有相关Cookie,跳转登录页
- 当拦截到
可选方案:提前预判刷新
如果不想等请求返回过期再刷新,可以让后端在登录、刷新成功的响应中,额外返回access token的到期时间戳(存储在普通可读取Cookie或者响应体中),前端每次发起请求前判断:如果当前时间距离到期时间小于预设阈值(比如30秒),先暂停当前请求,完成刷新后再发起业务请求即可。
注意事项
- 刷新请求失败后要清空暂存的请求队列,避免重复抛出错误
- 用户退出登录时,后端要主动作废数据库中存储的refresh token,同时清空浏览器中两个令牌的Cookie
内容的提问来源于stack exchange,提问作者Stach_batya
相关产品推荐
相关产品推荐

