关于OAuth多种令牌/授权码类型设计逻辑及刷新令牌过期处理的技术问询
OAuth多种令牌/授权码类型设计逻辑及刷新令牌过期处理的技术问询
嘿,这个问题问到点子上了——OAuth这套令牌体系看似繁琐,但每一环都是为了平衡安全性和用户体验,咱们掰开揉碎了说:
为什么要分三种令牌/授权码?
每个角色的职责和安全边界都不一样:
- 授权码(Authorization Code):它是用户授权后,给你的应用的「临时通行证」,短有效期(10分钟)+ 一次性使用的设计,核心是为了避免令牌泄露风险。因为授权码是在浏览器跳转的过程中传递的,很容易被中间人盯上;但它只能用来兑换一次访问令牌,而且兑换时还需要你的应用后端拿出只有服务器知道的客户端密钥验证——就算授权码被截,攻击者也没法拿到真正能调用API的访问令牌。要是把它设成90天有效期,那被泄露的风险就会指数级上升。
- 访问令牌(Access Token):这是直接用来调用API的「门票」,短有效期(1小时)的原因很简单:缩小泄露后的危害范围。万一访问令牌被偷,攻击者最多也就有1小时的时间滥用它,不会长期霸占用户的资源。而且访问令牌通常是轻量化的(比如JWT),API服务能快速验证有效性,不用每次都查数据库,性能更优。
- 刷新令牌(Refresh Token):它是用来「续期」的长期凭证,有效期90天左右,但它只会存放在你的应用后端,永远不会暴露给前端页面或客户端。这样既实现了「不用反复打扰用户授权」的体验,又把高风险的长期凭证放在了安全的服务器环境里。另外很多服务商还支持刷新令牌轮换——每次用旧的刷新令牌换访问令牌时,会返回一个新的刷新令牌,旧的立刻失效,就算旧令牌泄露也没用。
为什么不直接用90天的授权码?
这完全是安全层面的考量:授权码是在公开的前端流程里传递的,长有效期的授权码一旦被拦截,攻击者就能拿着它去兑换访问令牌(尤其是像单页应用这类没有后端的场景,甚至不需要客户端密钥就能兑换),相当于把用户的资源长期暴露在风险里。而且OAuth的设计原则就是「职责分离」——授权码只负责证明用户同意了,访问令牌负责API访问,刷新令牌负责续期,这样每一环的风险都可控,出问题也能快速定位。
刷新令牌过期后是不是必须重新让用户授权?
没错,主流的OAuth服务商(包括Azure AD和Google)都是这个逻辑。刷新令牌过期后,你就失去了无需用户交互就能获取新令牌的权限,必须重新引导用户走完整的授权流程,让用户再次确认同意你的应用访问他们的资源。有些服务商可能提供了延长刷新令牌有效期的配置(比如Azure AD的持久刷新令牌),但核心规则不变:一旦刷新令牌失效,必须用户重新授权。
备注:内容来源于stack exchange,提问作者Phil Rosenberg




