OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回access_token(用于通过资源验证自己)和refresh_token,refresh_taken纯粹用于创建新的access_token:
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
为什么两者都有?为什么不让access_token和refresh_token一样长,而不设置refresh_taken?
OAuth 2.0协议草案的第4.2节指出,授权服务器可以返回access_token(用于通过资源验证自己)和refresh_token,refresh_taken纯粹用于创建新的access_token:
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
为什么两者都有?为什么不让access_token和refresh_token一样长,而不设置refresh_taken?
当前回答
这个答案是在两位高级开发人员(约翰·布莱顿和大卫·詹内斯)的帮助下得出的。
使用刷新令牌的主要原因是减少攻击面。
假设没有刷新键,让我们来看看这个示例:
一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。在30分钟结束时,我必须把旧钥匙交给钥匙制造商,并获得一把新钥匙。
如果我是黑客,拿到了你的钥匙,那么在30分钟结束后,我会把它快递给钥匙制造商,并获得一把新钥匙。无论换钥匙,我都能连续打开所有车门。
问:在这30分钟里,我有多少次破解钥匙的机会?每次你使用密钥时,我都有80次黑客攻击的机会(把这看作是发出网络请求并传递访问令牌以识别自己)。这是80倍的攻击面。
现在让我们来看看同一个例子,但这次我们假设有一个刷新键。
一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。要获取新密钥,我无法传递旧的访问令牌。我只能通过刷新键。
如果我是黑客并得到了你的密钥,我可以使用它30分钟,但在30分钟结束时,将它发送给密钥制作者没有任何价值。如果我这样做了,那么密钥制作者只会说“此令牌已过期。您需要刷新令牌。”为了能够扩展我的黑客攻击,我必须将信使黑客攻击给密钥制作者。信使有一个不同的密钥(将其视为刷新令牌)。
问题:在30分钟内,我有多少次违反刷新键的黑客攻击机会?80? 不,我只有一次黑客攻击机会。在这段时间里,快递员与钥匙制造商进行沟通。这是1X攻击面。我确实有80次破解钥匙的机会,但30分钟后就不行了。
服务器将根据凭证和JWT的签名(通常)验证访问令牌。
访问令牌泄漏是不好的,但一旦过期,它对攻击者不再有用。刷新令牌泄漏的情况要糟糕得多,但估计可能性较小。(我认为,刷新令牌泄漏的可能性是否比访问令牌泄漏的概率低得多,这是一个问题,但这就是想法。)
重点是访问令牌被添加到您发出的每个请求中,而刷新令牌仅在刷新流期间使用所以MITM看到代币的可能性很小
频率有助于攻击者。像SSL中的潜在安全漏洞、客户端中的潜在的安全漏洞以及服务器中潜在的安全缺陷等令人心碎的漏洞都使泄漏成为可能。
此外,如果授权服务器与处理其他客户端请求的应用服务器分离,那么该应用服务器将永远不会看到刷新令牌。它只会看到不会持续很久的访问令牌。
分隔有利于安全。
最后但并非最不重要的刷新令牌可以被旋转。意思是“每次客户端请求将刷新令牌交换为新的访问令牌时,都会返回新的刷新令牌”。随着刷新令牌的不断交换和失效,威胁降低。举个例子:令牌通常在TTL之后过期,通常是一小时。
刷新令牌并不总是,但通常会在使用时被撤销,并发出新的令牌。这意味着,如果您在检索新的刷新令牌时发生网络故障,那么下次发送该刷新令牌时,它将被视为已吊销,您必须登录。
有关旋转的更多信息,请参阅此处和此处
总结
降低频率分区令牌的轮换(更快的失效)和更精细的管理(过期时间或请求数量)。
所有这些都有助于减轻威胁
关于这个问题的另一个观点,请看这个令人敬畏的答案
刷新令牌与什么无关?
通过刷新令牌更新/撤销访问级别的能力是选择使用刷新令牌的一个副产品,否则独立访问令牌可能会被撤销,或在其过期时修改其访问级别,用户将获得新令牌
其他回答
为什么不让access_token和refresh_token一样长不吃点心吗?
除了其他人提供的出色答案之外,我们使用刷新令牌还有另一个原因,这与声明有关。
每个令牌都包含声明,这些声明可以包括用户名、用户角色或创建声明的提供者等任何内容。当刷新令牌时,这些声明将被更新。
如果我们更频繁地刷新令牌,显然会给我们的身份服务带来更大的压力;然而,我们正在获得更准确和最新的声明。
我在这里获得了一些额外的资源,这些资源澄清了我们为什么需要refresh_token的某些问题。这些资源的一些要点如下:
在现实世界中,最好使用名为authServer和resourceServer/s的独立服务器authServer-仅用于身份验证和授权。该服务器的职责是发布刷新令牌、访问令牌以及登录和注销用户resourceServer-此服务器(也可以是负载平衡的多个服务器)提供受保护的数据。例如,这些数据可以像电子商务项目中的产品、评论等refresh_token的一个用途是,每次需要新的access_token时,我们不必通过网络(从前端到authServer)发送用户名和密码(凭据)。这应该只在第一次完成(当您还没有refresh_token时),refresh_taken将立即从authServer获取新的access_token,这样您就可以继续向受保护的resourceServer发出请求。这里的优点是,用户不必每次都提供凭据,因此用户的用户名和密码不容易被泄露。refresh_token的另一个主要用途是,假设您的authServer与现实世界中的resourceServer(第三方服务,如auth0、okta、azure等,或您自己的实现)相比非常受保护。您只需将access_token发送到resourceServer(以获取数据),而无需向resourceServer发送refresh_token。因此,当您的access_token发送到resourceServer时,很有可能会有黑客拦截您的resourceServer(因为它不像authServer那样安全),从而访问您的短暂访问权。因此,access_token的寿命很短(例如30分钟)。记住,当这个access_token过期时,您将向authServer(它比resourceServer更安全)发送refresh_token以获取新的access_toke。由于您在任何时候都不会向resourceServer发送refresh_token,因此拦截resourceServer的黑客不可能获得您的refresh_taken。如果作为一名开发人员,您仍然怀疑用户的refresh_token也可能被黑客入侵,那么您可以注销所有用户(使refresh_taken对所有用户无效),这样用户将再次登录(提供用户名和密码)以获得新的refresh_token+access_token,事情将再次步入正轨。
一些有用的资源
具有或不具有刷新令牌的工作流-Youtube
JWT认证代码示例-节点JS-Youtube
这个答案来自Justin Richer通过OAuth 2标准正文电子邮件列表。这是在他的许可下发布的。
刷新令牌的生命周期取决于(AS)授权服务器-它们可以过期、被撤销等。刷新令牌和访问令牌的区别在于受众:刷新令牌只返回授权服务器,访问令牌返回(RS)资源服务器。
此外,仅仅获得访问令牌并不意味着用户已经登录。事实上,用户可能已经不在那里了,这实际上是刷新令牌的预期用例。刷新访问令牌将允许您代表用户访问API,但不会告诉您用户是否在那里。
OpenIDConnect不仅从访问令牌提供用户信息,还提供ID令牌。这是一个单独的数据块,指向客户端本身,而不是AS或RS。在OIDC中,如果您可以获得一个新的ID令牌,您应该只考虑某人实际通过协议“登录”。刷新它可能还不够。
有关更多信息,请阅读http://oauth.net/articles/authentication/
为了进一步简化B T的答案:当您通常不希望用户再次输入凭据,但仍然希望能够撤销权限(通过撤销刷新令牌)时,请使用刷新令牌
您不能撤销访问令牌,只能撤销刷新令牌。
让我们考虑一个系统,其中每个用户链接到一个或多个角色,每个角色链接到一种或多种访问权限。可以缓存这些信息以获得更好的API性能。但是,用户和角色配置可能会发生变化(例如,可能会授予新的访问权限,或者可能会撤销当前的访问权限),这些都应该反映在缓存中。
我们可以为此目的使用访问和刷新令牌。当使用访问令牌调用API时,资源服务器检查缓存的访问权限。如果有任何新的访问许可,则不会立即反映。一旦访问令牌过期(例如在30分钟内)并且客户端使用刷新令牌生成新的访问令牌,就可以使用来自DB的更新的用户访问权限信息来更新缓存。
换句话说,我们可以将昂贵的操作从使用访问令牌的每次API调用转移到使用刷新令牌生成访问令牌的事件。