我必须承认,这个问题我一直持有很长时间,但从未真正理解。
假设授权令牌就像一个保险柜的钥匙,当它过期后就无法再使用。现在我们得到了一个神奇的刷新令牌,可以用它来获取另一个可用的钥匙,然后继续下去...直到神奇令牌过期。那么为什么不将授权令牌的过期时间与刷新令牌设置为相同呢?根本没有必要吗?
这是什么原因呢?是历史原因吗?
我必须承认,这个问题我一直持有很长时间,但从未真正理解。
假设授权令牌就像一个保险柜的钥匙,当它过期后就无法再使用。现在我们得到了一个神奇的刷新令牌,可以用它来获取另一个可用的钥匙,然后继续下去...直到神奇令牌过期。那么为什么不将授权令牌的过期时间与刷新令牌设置为相同呢?根本没有必要吗?
这是什么原因呢?是历史原因吗?
我最近阅读了Taiseer Joudeh的一篇文章,发现它非常有用,他说:
在我看来,使用刷新令牌有三个主要好处,它们是:
更新访问令牌内容:你知道访问令牌是自包含的令牌,一旦生成,它们包含有关已认证用户的所有权利声明(信息)。现在,如果我们为名为“Alex”的用户颁发了一个长期有效的令牌(例如一个月时间)并将其注册为“用户”角色,则此信息被包含在授权服务器生成的令牌中。如果您稍后决定(在他获得令牌后的两天内)将其添加到“管理员”角色,则无法更新令牌中包含的此信息,需要要求他再次进行身份验证,以便授权服务器将此信息添加到新生成的访问令牌中,但在大多数情况下这是不可行的。您可能无法联系到获得长期访问令牌的用户。因此,为解决此问题,我们需要颁发短期有效的访问令牌(例如30分钟),并使用刷新令牌获取新的访问令牌。一旦您获得新的访问令牌,授权服务器将能够为用户“Alex”添加新的声明,将其分配到“管理员”角色中,一旦生成了新的访问令牌。
撤销已认证用户的访问:一旦用户获得长期有效的访问令牌,只要他的访问令牌没有过期,他就能够访问服务器资源,除非授权服务器实现自定义逻辑(强制您在数据库中存储生成的访问令牌,并在每个请求中进行数据库检查),否则没有标准方式可以撤销访问令牌。但是使用刷新令牌,系统管理员可以通过简单地从数据库中删除刷新令牌标识符来撤销访问权限,因此,一旦系统使用已删除的刷新令牌请求新的访问令牌,授权服务器将拒绝此请求,因为刷新令牌不再可用(我们将更详细地介绍这一点)。
无需存储或请求用户名和密码:使用刷新令牌允许您在用户第一次进行身份验证后仅一次请求其用户名和密码,然后授权服务器可以发行非常长期的刷新令牌(例如1年),用户将保持登录状态直到系统管理员尝试撤销刷新令牌。您可以将此视为对服务器资源进行离线访问的方法,如果您正在构建一个将由前端应用程序消耗的API,并且频繁要求用户名/密码不可行,那么这将很有用。
我想要补充另一种观点。
假设您想要创建一个无状态(无会话)的安全机制,可以对数百万用户进行身份验证,而无需进行数据库调用以进行身份验证。随着应用程序所获得的所有流量,减少每个请求中的数据库调用是很值得的!它需要是无状态的,因此可以轻松地集群和扩展到数百甚至数千台服务器。
在传统的会话中,用户登录后,我们从数据库中读取其用户信息。为了避免不断读取,我们将其存储在会话(通常是内存或某些集群缓存中)。我们将会话ID作为cookie发送给客户端,并附加到所有后续请求中。在后续请求中,我们使用会话ID查找会话,该会话反过来包含用户信息。
但我们不想使用会话。因此,不要将用户信息存储在会话中,而是将其直接放入访问令牌中。我们对令牌进行签名,以防止任何人篡改它。这样就可以在没有会话且无需为每个请求查找用户信息的情况下进行身份验证。
但是,没有会话有一个很大的缺点。例如,如果此用户被封禁怎么办?在旧情景中,我们只需删除他的会话。然后,他必须重新登录,但他将无法这样做。封禁完成。但在新情景中没有会话。那么我们该如何封禁他呢?我们必须(非常礼貌地)要求他删除访问令牌。检查每个传入请求是否在禁令名单中?是的,可以工作,但现在我们又不得不进行我们不想要的数据库调用。
参考答案(via @Anders)很有帮助,它指出:
在发生妥协的情况下,其有效时间很短,但令牌是通过SSL使用的,因此不太可能被攻击者获取。
我认为重要的部分是访问令牌通常会被记录(特别是当作为查询参数使用时,这对于JSONP很有用),因此最好让它们具有短暂的生命周期。
对于服务提供商大规模实现OAuth 2.0,还有另外一些原因:
如果可以不担心撤销,API服务器可以安全地验证访问令牌而无需进行数据库查找或RPC调用。这可以对API服务器产生强大的性能优势并减少复杂性。最好是允许令牌撤销需要花费30分钟到1小时(或访问令牌的长度)。当然,API服务器也可以保留在内存中列出的最近1小时内吊销的令牌列表。
由于令牌可以具有多个范围并访问多个不同的API服务,具有短暂的访问令牌可以防止API服务的开发人员获得对API服务B中用户数据的终身访问权限。分区对于安全性是有利的。
简短的回答:
刷新令牌允许对令牌进行不同形式的作用域和衰减时间设置。实际资源令牌生命周期短暂,而刷新令牌可以保持有效多年(移动应用程序)。这提供了更好的安全性(不需要保护资源令牌)和性能(只有刷新令牌API需要检查DB的有效性)。