这两个 token 的存在是为了化解一个直接的矛盾:access token 必须在每个 request 上发送(因此暴露得很多),但你又想要持续很久的 session,而不必频繁强制登录。你无法在单个 token 里安全地兼得两者——所以你把这份工作拆开。
Authorization header 中发送。因为它被不断传输,泄露很可能发生;保持其短命意味着被偷走的那个几乎立刻就过期。Login ──▶ access (15m) + refresh (30d)
每次 API 调用 ──▶ 发送 access
Access 已过期 ──▶ 发送 refresh ──▶ 新 access (+ 轮换后的 refresh)
| 一个长寿命 access token | Access + refresh | |
|---|---|---|
| 暴露 | 每个 request 都发送、存活久 → 盗窃窗口大 | Access 短寿命;refresh 极少发送 |
| 撤销 | 难(stateless JWT 无法收回签发) | 撤销 refresh token;access 在几分钟内失效 |
| UX | 若短命则频繁重新登录 | 无需重新输入凭据即可保持登录 |
| 泄露的影响半径 | 大 | 小(access 很快过期) |
httpOnly cookie 中,避开 XSS 的触及。这是现代标准的 auth 设计,面试官问它是想看你是否理解为什么,而不仅仅是怎么做。关键洞见在于取舍:无状态与短暴露(access)对长 session 与可撤销性(refresh)。做错了——一个长寿命 access token、没有 rotation、把 refresh 存在 localStorage 里——就会把单个泄露的 token 变成长期的账户失陷。说得出这种拆分以及每个 token 各自换来了什么,正是一个有安全意识的工程师应当知道的。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠