什么是刷新令牌的意义?

wan*_*gii 42 authentication oauth access-token refresh-token

我必须承认我已经有很长一段时间没有这个问题,从来没有真正理解过.

说auth令牌就像一个保险箱的钥匙,当它到期时它不再可用了.现在我们给了一个魔术刷新令牌,可用于获取另一个可用的键,另一个......直到魔术键到期.那么为什么不将auth令牌的到期时间设置为与刷新令牌相同?为什么这么麻烦?

它的正当理由是什么,也许是历史原因?真的很想知道.谢谢

Kia*_*ash 40

前几天我正在读Taiseer Joudeh 的一篇文章,我发现它非常有用,他说:

在我看来,使用刷新令牌有三个主要好处:

  1. 更新访问令牌内容:如您所知,访问令牌是自包含令牌,它们包含有关经过身份验证的用户生成后的所有声明(信息),现在如果我们为用户发出长期令牌(例如1个月)命名为"Alex"并将其注册为"用户"角色,然后此信息包含在授权服务器生成的令牌中.如果您稍后决定(他获得令牌后2天)将其添加到"管理员"角色,则无法更新生成的令牌中包含的此信息,您需要让他再次重新验证他自己因此授权服务器将此信息添加到此新生成的访问令牌中,这在大多数情况下都不可行.您可能无法覆盖获得长期访问令牌的用户.因此,要解决此问题,我们需要发布短期访问令牌(例如30分钟)并使用刷新令牌获取新的访问令牌,一旦获得新的访问令牌,授权服务器将能够为用户添加新的声明"Alex"在生成新的访问令牌后将其分配给"Admin"角色

  2. 撤消对经过身份验证的用户的访问:一旦用户获得长期访问令牌,只要他的访问令牌未过期,他就能够访问服务器资源,除非授权服务器实现自定义逻辑,否则没有标准方法来撤销访问令牌这会强制您将生成的访问令牌存储在数据库中,并对每个请求执行数据库检查.但是使用刷新令牌,系统管理员可以通过简单地从数据库中删除刷新令牌标识符来撤销访问权限,因此一旦系统使用已删除的刷新令牌请求新的访问令牌,授权服务器将拒绝此请求,因为刷新令牌不再可用(我们将详细介绍这一点).

  3. 无需存储或询问用户名和密码:使用刷新令牌可以让您在第一次进行身份验证后只询问用户一次用户名和密码,然后授权服务器可以发出非常长的刷新令牌(1年为除非系统管理员试图撤销刷新令牌,否则用户将在所有这段时间内保持登录状态.您可以将此视为对服务器资源进行脱机访问的一种方法,如果您正在构建一个将由前端应用程序使用的API,这种情况非常有用,因为不可能经常询问用户名/密码.

  • 为什么不使用一个短期访问令牌,在它过期时检查凭据?如果用户仍然有效,则重置访问令牌的到期时间。我不明白需要刷新令牌吗? (2认同)

Rya*_*oyd 14

引用的答案(通过@Anders)很有用,它说明:

在妥协的情况下,它有效的时间窗口是有限的,但令牌通过SSL使用,因此不太可能受到损害.

我认为重要的部分是访问令牌通常会被记录(特别是当用作查询参数时,这对JSONP很有帮助),所以最好让它们短暂存在.

服务提供商大规模实施OAuth 2.0还有一些其他原因:

  1. 如果可以不担心撤销,API服务器可以安全地验证访问令牌而无需DB查找或RPC调用.这可以带来强大的性能优势并降低API服务器的复杂性.如果您可以使用30m-60m(或任何访问令牌长度)的令牌撤销,那么最好.当然,API服务器也可以在过去一小时内保留内存中的令牌列表.

  2. 由于令牌可以具有多个可以访问多个不同API服务的作用域,因此具有短期访问令牌可以防止API服务的开发人员终身访问API服务B上的用户数据.区域划分有利于安全性.

  • @wangii - Re#1 - 访问令牌可以使用加密或签名进行自我验证,因此无需进行数据库查询或RPC调用.刷新令牌可以在OAuth提供商处保持不透明和可撤销.Re#2 - 是的,访问令牌的范围是相同的.但是,给服务开发者(A)终身访问用户的服务数据(B)要比仅在用户主动使用服务(A)时才允许他们访问更糟糕. (3认同)

Sti*_*itt 13

我想补充一点另一个观点.

无状态身份验证,无需在每个请求上访问数据库

假设您想要创建一个无状态(无会话)安全机制,可以对数百万用户进行身份验证,而无需进行数据库调用来进行身份验证.随着您的应用程序获得的所有流量,在每个请求上保存数据库调用是值得的!它需要是无状态的,因此它可以轻松集群并扩展到数百甚至数千台服务器.

使用老式会话,用户登录,此时我们从数据库中读取他们的用户信息.为了避免不得不一次又一次地读取它,我们将它存储在一个会话中(通常在内存或某些集群缓存中).我们将会话ID发送到cookie中的客户端,该cookie附加到所有后续请求.在后续请求中,我们使用会话ID来查找会话,而会话又包含用户信息.

将用户信息直接放在访问令牌中

但是我们不想要会话.因此,不要将用户信息存储在会话中,而是将其放入访问令牌中.我们签署令牌,以便没有人可以篡改它并预先安装.我们可以在没有会话的情况下对请求进行身份验证,而无需从每个请求的DB中查找用户信息.

没有会话......没办法禁止用户?

但没有一个会议有一个很大的缺点.如果这个用户被禁止怎么办?在旧方案中,我们只删除他的会话.然后他必须再次登录,这是他无法做到的.禁令完成.但在新的情况下,没有会话.那我们怎么禁止他呢?我们必须(非常礼貌地)要求他删除他的访问令牌.根据禁令列表检查每个传入的请求?是的,会工作,但现在我们再次必须进行我们不想要的数据库调用.

与短命令牌妥协

如果我们认为用户可能仍然可以使用他的帐户,比如说,在被禁止后10分钟,我们可以创建一种情况,这是在每次请求检查数据库和仅登录时的折衷.这就是刷新令牌的用武之地.它们允许我们使用具有短期访问令牌的无状态机制.我们无法撤销这些令牌,因为没有对它们进行数据库检查.我们只根据当前时间检查他们的到期日.但是一旦它们到期,用户将需要提供刷新令牌以获得新的访问令牌.此时我们检查数据库,看到用户已被禁止.因此,我们拒绝访问令牌的请求,禁令生效.

  • “但是一旦过期,用户将需要提供刷新令牌才能获取新的访问令牌”。为什么要刷新令牌呢?为什么不根据原始令牌中的凭据重新验证用户,然后如果有效,则重置该令牌的到期日期? (4认同)
  • 好的,谢谢,但如果我们忽略我写的关于根据访问令牌中的凭据重新验证用户的内容(这可能只是检查用户 ID 是否仍然被允许),我仍然认为没有刷新令牌的理由。这就是我的问题:“为什么要刷新令牌?” (3认同)
  • @RickJolly因为访问令牌通常不包含凭据(刷新令牌也不包含)。它的工作方式是令牌由发行者签名。因此,发行者知道令牌是有效的(直到令牌过期)。通常,令牌包含诸如用户名和用户拥有的角色/权限之类的东西。然后,双方都可以使用令牌显示此类信息,而不必先执行DB /网络调用。 (2认同)
  • @RickJolly 点已采取。我猜协议的设计者得出的结论是,最简单的方法是拆分两个任务:为所有操作提供访问令牌,并提供刷新令牌只是为了获取访问令牌。这将刷新的责任交给了客户端,从而降低了服务器的复杂性。 (2认同)

B M*_*B M 5

短裤可能的答案:

刷新令牌允许令牌的范围/不同的衰减时间。实际资源令牌的生命周期很短,而刷新令牌可以保持多年有效(移动应用程序)。这带来了更好的安全性(资源令牌不必受到保护)和性能(只有刷新令牌 API 必须检查数据库的有效性)。

  • 这对我来说似乎是最清晰和最好的答案......谢谢。 (2认同)