前言
本文聊聊 token 和 refresh token
这哥俩经常在【身份认证(Authentication)】和【授权(Authorization)】系统中成对出现,共同协作来平衡【安全性(Security)】与【用户体验(User Experience)】。
之前你可能接触过 Access Token 的概念,现在来看看它的好搭档 ------ Refresh Token。
【本文目标】:理解它们各自的职责、协作方式,以及为什么需要这样的设计。
正文
一、Access Token(访问令牌)
我们通常简称的 【Token】 ,在很多场景下特指的就是 【Access Token(访问令牌)】。
它是客户端在登录后获取的、用于直接访问受保护资源的【凭证】。
当客户端向服务器的 API 发起请求时,必须在【HTTP Header】(通常是 Authorization
头)中携带此 Token,服务器会验证该 Token 的有效性,然后决定是否授予访问权限。
关键特性:
- 短命的(Short-lived) :出于安全考虑,Access Token 的【有效期(Expiration Time)】通常设置得较短,比如 15 分钟、1 小时。这样即使 Token 意外泄露,攻击者能使用它的时间窗口也非常有限。
可以把 Access Token 想象成一张【电影票】。你买票(登录)后,在有效期内(电影开场前)可以凭票(Token)入场(访问资源)。但这场电影放完了(Token 过期),票就作废了。
二、Refresh Token(刷新令牌)
【Refresh Token(刷新令牌)】 是专门用来获取新的 Access Token 的凭证。
它是在用户首次登录认证时,与 Access Token 一同由认证服务器颁发给客户端的。当 Access Token 过期后,客户端不是让用户重新登录,而是使用这个 Refresh Token 向认证服务器请求一个新的、有效的 Access Token。
关键特性:
- 长命的(Long-lived) :Refresh Token 的有效期比 Access Token 长得多,可能是几天、几周、甚至数月。
- 不直接访问资源 :Refresh Token 不能 直接用于访问业务 API 或资源服务器。它的权限仅限于向认证服务器申请新的 Access Token。
- 存储更安全:由于生命周期长且权限关键,Refresh Token 需要在客户端以更安全的方式存储(例如,移动端使用【安全存储(Secure Storage)】,Web 端使用【HttpOnly Cookie】),以防泄露。
继续用电影票的比喻:Refresh Token 就像你的【会员卡】。单场电影票(Access Token)过期了,但你不用重新排队买票(重新登录),只需出示会员卡(Refresh Token)就能兑换一张新的电影票(新的 Access Token),从而连续观看多场电影(保持登录状态)。
你可能会有的疑问
🤔 那 refresh token 泄露了,不照样炸锅吗??
确实,如果 Refresh Token 泄露了,攻击者确实能长期获取新的 Access Token,危害极大。因此,安全措施的核心就在于 "限制 Refresh Token 的使用并使其可被检测和撤销":
通过将 Refresh Token 绑定于特定的客户端(验证客户端信息)、设置相对较长的但非永久有效的过期时间、以及最重要的是由服务器维护一个可主动撤销的令牌状态机制,一旦发现泄露,服务器立即使该 Refresh Token 失效,从而将损失降到最低。这正是它比单纯延长 Access Token 有效期更安全的原因。
三、Token 与 Refresh Token 的协作流程
它们是如何配合工作的?一个典型的流程如下:
- 用户登录:用户提供凭证(如用户名密码),客户端将其发送至认证服务器。
- 颁发双 Token :认证服务器验证凭证通过后,同时生成 并返回一个 Access Token 和一个 Refresh Token 给客户端。
- 访问资源:客户端使用 Access Token 访问受保护的资源。在 Token 有效期内,这一步可重复进行。
- Access Token 过期 :当客户端再次使用 Access Token 访问资源时,资源服务器返回错误(如
401 Unauthorized
),提示 Token 已失效。 - 使用 Refresh Token :客户端不提示用户登录,而是悄无声息地 将 Refresh Token 发送到认证服务器的特定接口(如
/auth/refresh
),请求一个新的 Access Token。 - 颁发新 Access Token:认证服务器验证 Refresh Token 的有效性。如果有效,则颁发一个新的 Access Token 给客户端(有时也会同时颁发一个新的 Refresh Token,这取决于安全策略)。
- 重试请求:客户端用新获取的 Access Token 重新发起之前失败的资源请求。
- Refresh Token 过期 :如果 Refresh Token 也过期或被撤销,则认证服务器会拒绝刷新请求。此时,客户端必须 引导用户重新进行登录认证。
四、为什么需要这样的设计?(核心优势)
为什么不一劳永逸地只用一个长期有效的 Token?为什么要设计两套令牌系统?
核心目的是为了在安全 和用户体验之间取得最佳平衡。
-
提升安全性(Security)
- Access Token 的"短命"特性,极大地降低了它泄露后带来的风险。即使被窃取,攻击者能造成的破坏时间也很短。
- Refresh Token 虽然"长命",但它不直接暴露给资源服务器,只与受信任的认证服务器通信,且可以被安全地存储。即使 Access Token 泄露,攻击者也无法通过它获取新的 Token。
- 吊销(Revocation)控制:服务器可以随时使某个 Refresh Token 失效(例如用户主动登出、检测到可疑活动时),从而立即终止该用户所有后续的 Access Token 获取能力。相比之下,要让一个已经签发出去的短期 Access Token 立即失效,实现起来更复杂(通常需要维护一个黑名单)。
-
改善用户体验(User Experience)
- 用户登录一次后,可以在很长一段时间内(Refresh Token 的有效期内)无需再次输入密码,实现了【静默认证(Silent Authentication)】或【"记住我"】功能,保证了使用的流畅性。
最后
回到最初的问题:
Token(通常指 Access Token) 和 Refresh Token 的关系是什么?
👇👇
Access Token 是用于直接访问受保护 API 资源的短期凭证,其短暂的有效期旨在降低泄露后的风险。
Refresh Token 是用于在 Access Token 过期后,无需用户再次认证即可获取新 Access Token 的长期凭证。
二者的核心关系是:通过 Refresh Token 的长效性来换取新的 Access Token,从而在维持用户持续登录状态(良好体验)的同时,依靠 Access Token 的短期有效性来提升整体安全性。
相关链接
- OAuth 2.0 RFC 6749 - OAuth 2.0 框架标准,其中明确定义了 Access Token 和 Refresh Token。
- What Are Refresh Tokens and How to Use Them Securely? - 关于 Refresh Token 安全使用的深入探讨。