告别频繁登录:打造用户无感的 Token 刷新机制

38 阅读3分钟

🧠 什么是“无痛刷新 Token”?

无痛刷新 Token 指的是:

当前端发送请求时,如果 access token 过期,系统会自动、悄无声息地用 refresh token 换一个新的 access token,并自动重试原始请求,整个过程对用户是完全无感知的,无需手动刷新页面或重新登录。

🚶‍♂️举个例子

🚉 地铁进站场景

  • 你买了一张短期票(access token),有效期是 15 分钟。
  • 同时,你还有一张长期通行证(refresh token),可以用来换新的短期票。

✅ 正常使用

  • 你在地铁站刷短期票进闸(发请求)。
  • 时间没过,成功通过(请求成功)。

⛔ 短期票过期

  • 你在站台等了太久,15 分钟过去了,想继续转线。
  • 这时候短期票(access token)过期了,不能继续用。

🤖 “无痛刷新”登场!

  • 你身上有长期通行证(refresh token)。
  • 系统自动帮你在后台排队 → 换了一张新的短期票(新 access token)。
  • 你重新刷一下 → 顺利进闸(自动重试请求)。
  • 你自己根本没感觉到有票换了,完全无感知,整个过程“无痛”完成 ✅

❌ 如果连通行证也失效了呢?

  • 比如你长期没上地铁,通行证(refresh token)也过期了。
  • 这时候,系统说:“请重新购票(登录)。”

🧠 实现思路:无痛刷新 Token

  1. 使用双token机制
  • 短期token(accessToken):用于接口调用,有效期短,一般是分钟级。
  • 长期token(refreshToken):用于刷新短期token,有效期较长,一般周或月级。
  1. 每次请求时 在header中携带accessToken
  • 如果accessToken过期(条件为约定的状态码 一般为401),调用服务的刷新短期token的接口,携带refreshToken
  • 获取到新的accessToken后,将新的accessToken放到header中,继续请求接口
  • 如果长期token也过期,则跳转到登录页面,重新登录(下面使用滑动过期时间来延长有效期)
  1. 前端在相应拦截器中判断是否过期,如果过期则调用刷新接口,获取新的token,并继续请求接口
[客户端发起请求]
    |
    v
[Access Token 还有效?]
    ├─✔ 是 → 直接请求接口
    └─✘ 否 → 进入刷新逻辑
            |
            v
        [Refresh Token 有效?]
            ├─✔ 是 → 刷新 Access Token → 重新发起原始请求
            └─✘ 否 → 引导用户重新登录

🧠 实现步骤

  1. 服务端设置三个必要接口
  • 没有token时,获取生成两个token的接口
  • 刷新token的接口
  • 清除token的接口
  1. 滑动过期时间
  • 在请求刷新接口时候,返回新的短期token,同时重置长期token的过期时间 使其在活跃状态不过期

长期token一般使用redis管理存储

如果我们把 Refresh Token 存在 Redis 里,并设置了滑动过期(每次续签就 EXPIRE 延长 7 天),
但 Refresh Token 本身(JWT)也有固定的 exp 过期时间,
那当它 JWT 内部过期了(比如 7 天后),Redis 即使还存着,也没用了?

✅ 做法

  1. 在生成长期token时 不设置过期时间 或设置极长的过期时间 (比如10年)
  2. redis来控制长期token的过期时间, 如果redis过期则token过期
  3. 在刷新token时,先判断refreshToken是否过期,如果过期则清除长期token,并引导用户重新登录
  4. 如果长期token未过期,则刷新短期token,并在redis重置长期token的存储时间

🔐 安全性

不再相信token自己的过期时间
而是相信redis的过期时间
redis中存在即有效,不存在即过期
所以即使token被截获,没有redis的配合,也是无效的

🧠 小结:

“无痛刷新”是前后端联手打造的,兼顾安全和体验的 Token 续期机制:短期 token 安全、长期 token 稳定、整个过程用户无感知。