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?


当前回答

为了理解这个问题的答案,我们需要了解两点。

第一点是,有时用户的访问令牌可能会在用户不知情的情况下被盗。由于用户不知道攻击,他们将无法手动通知我们。然后,就我们给攻击者完成攻击的时间(机会)而言,15分钟和一整天之间会有巨大的差异。因此,这就是我们需要每“短时间”(例如,每15分钟)“刷新”访问令牌的原因,我们不想将此操作推迟很长时间(例如,一整天)。因此,OP在问题中所说的显然不是一个选项(将访问令牌的到期时间延长到刷新令牌的有效时间)。

因此,我们至少还有以下两个选择:

要求每个用户每隔一段时间重新输入他们的凭据,以便为他们提供新的访问令牌。但显然,这不是一个流行的选项,因为它会困扰用户。使用刷新令牌。阅读下面的第二点,以了解其工作原理(背后的逻辑)。

第二点需要理解的是,因为我们已经将访问令牌与刷新令牌分开,现在可以以“不同的方式”发送刷新令牌,因此我们可以以攻击者的JavaScript(通常是客户端代码)无法访问的方式发送它,例如,使用httpOnly标记:

HttpOnly Cookie是添加到浏览器Cookie中的标记,用于阻止客户端脚本访问数据。来源

在生成cookie时使用HttpOnly标志有助于降低客户端脚本访问受保护cookie的风险。HttpOnly cookie于2002年由Microsoft Internet Explorer开发人员针对Internet Explorer 6 SP1首次实现。来源(感谢IE!)

因此,尽管攻击者仍然可以窃取访问令牌(强烈建议将其保存在RAM中,而不是本地存储等易受攻击的地方),但他们将无法窃取刷新令牌。因此,如果攻击者窃取了一个人的访问令牌,他们只有很短的时间滥用它(15分钟?比一整天好得多!),然后一旦它过期,他们就没有机会自己获得新的令牌。

其他回答

这个答案是在两位高级开发人员(约翰·布莱顿和大卫·詹内斯)的帮助下得出的。

使用刷新令牌的主要原因是减少攻击面。

假设没有刷新键,让我们来看看这个示例:

一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。在30分钟结束时,我必须把旧钥匙交给钥匙制造商,并获得一把新钥匙。

如果我是黑客,拿到了你的钥匙,那么在30分钟结束后,我会把它快递给钥匙制造商,并获得一把新钥匙。无论换钥匙,我都能连续打开所有车门。

问:在这30分钟里,我有多少次破解钥匙的机会?每次你使用密钥时,我都有80次黑客攻击的机会(把这看作是发出网络请求并传递访问令牌以识别自己)。这是80倍的攻击面。

现在让我们来看看同一个例子,但这次我们假设有一个刷新键。

一座大楼有80扇门。所有车门都用同一把钥匙打开。钥匙每30分钟更换一次。要获取新密钥,我无法传递旧的访问令牌。我只能通过刷新键。

如果我是黑客并得到了你的密钥,我可以使用它30分钟,但在30分钟结束时,将它发送给密钥制作者没有任何价值。如果我这样做了,那么密钥制作者只会说“此令牌已过期。您需要刷新令牌。”为了能够扩展我的黑客攻击,我必须将信使黑客攻击给密钥制作者。信使有一个不同的密钥(将其视为刷新令牌)。

问题:在30分钟内,我有多少次违反刷新键的黑客攻击机会?80? 不,我只有一次黑客攻击机会。在这段时间里,快递员与钥匙制造商进行沟通。这是1X攻击面。我确实有80次破解钥匙的机会,但30分钟后就不行了。


服务器将根据凭证和JWT的签名(通常)验证访问令牌。

访问令牌泄漏是不好的,但一旦过期,它对攻击者不再有用。刷新令牌泄漏的情况要糟糕得多,但估计可能性较小。(我认为,刷新令牌泄漏的可能性是否比访问令牌泄漏的概率低得多,这是一个问题,但这就是想法。)

重点是访问令牌被添加到您发出的每个请求中,而刷新令牌仅在刷新流期间使用所以MITM看到代币的可能性很小

频率有助于攻击者。像SSL中的潜在安全漏洞、客户端中的潜在的安全漏洞以及服务器中潜在的安全缺陷等令人心碎的漏洞都使泄漏成为可能。

此外,如果授权服务器与处理其他客户端请求的应用服务器分离,那么该应用服务器将永远不会看到刷新令牌。它只会看到不会持续很久的访问令牌。

分隔有利于安全。

最后但并非最不重要的刷新令牌可以被旋转。意思是“每次客户端请求将刷新令牌交换为新的访问令牌时,都会返回新的刷新令牌”。随着刷新令牌的不断交换和失效,威胁降低。举个例子:令牌通常在TTL之后过期,通常是一小时。

刷新令牌并不总是,但通常会在使用时被撤销,并发出新的令牌。这意味着,如果您在检索新的刷新令牌时发生网络故障,那么下次发送该刷新令牌时,它将被视为已吊销,您必须登录。

有关旋转的更多信息,请参阅此处和此处

总结

降低频率分区令牌的轮换(更快的失效)和更精细的管理(过期时间或请求数量)。

所有这些都有助于减轻威胁

关于这个问题的另一个观点,请看这个令人敬畏的答案


刷新令牌与什么无关?

通过刷新令牌更新/撤销访问级别的能力是选择使用刷新令牌的一个副产品,否则独立访问令牌可能会被撤销,或在其过期时修改其访问级别,用户将获得新令牌

为了进一步简化B T的答案:当您通常不希望用户再次输入凭据,但仍然希望能够撤销权限(通过撤销刷新令牌)时,请使用刷新令牌

您不能撤销访问令牌,只能撤销刷新令牌。

这一切都与扩展和保持资源服务器无状态有关。

您的服务器/资源服务器服务器是无状态的,这意味着不检查任何存储以快速响应。通过使用公钥验证令牌的签名来执行此操作。检查每个请求的access_token。通过只检查access_token的签名和过期日期,响应速度非常快,并允许扩展。access_token应该有很短的到期时间(几分钟),因为如果它被泄露,就没有办法撤销它。身份验证服务器/OAuth服务器服务器不是无状态的,但它可以,因为请求要少得多。仅在access_token过期时检查refresh_token。(例如每2分钟)请求速率远低于资源服务器。将刷新令牌存储在数据库中,并可以撤消它。refresh_token可能有很长的到期时间(几周/几个月),如果它被泄露,有办法撤销它。

不过有一个重要的注意事项,身份验证服务器的请求要少得多,因此可以处理负载,但是由于必须存储所有refresh_token,因此可能存在存储问题,如果用户急剧增加,这可能会成为一个问题。

这个答案来自Justin Richer通过OAuth 2标准正文电子邮件列表。这是在他的许可下发布的。


刷新令牌的生命周期取决于(AS)授权服务器-它们可以过期、被撤销等。刷新令牌和访问令牌的区别在于受众:刷新令牌只返回授权服务器,访问令牌返回(RS)资源服务器。

此外,仅仅获得访问令牌并不意味着用户已经登录。事实上,用户可能已经不在那里了,这实际上是刷新令牌的预期用例。刷新访问令牌将允许您代表用户访问API,但不会告诉您用户是否在那里。

OpenIDConnect不仅从访问令牌提供用户信息,还提供ID令牌。这是一个单独的数据块,指向客户端本身,而不是AS或RS。在OIDC中,如果您可以获得一个新的ID令牌,您应该只考虑某人实际通过协议“登录”。刷新它可能还不够。

有关更多信息,请阅读http://oauth.net/articles/authentication/

这些答案都没有找到刷新令牌存在的核心原因。显然,您总是可以通过将客户端凭据发送到身份验证服务器来获得新的访问令牌/刷新令牌对——这就是您首先获得它们的方式。

因此,刷新令牌的唯一目的是限制通过网络发送到身份验证服务的客户端凭据的使用。访问令牌的TTL越短,就越需要使用客户端凭据来获取新的访问令牌,因此攻击者就越有机会破坏客户端凭据(尽管如果使用非对称加密发送客户端凭据,这可能非常困难)。因此,如果您有一个一次性刷新令牌,您可以使访问令牌的TTL任意小,而不影响客户端凭据。