访问令牌应该自动刷新还是手动刷新?

All*_*uan 12 authentication access-token oauth-2.0 refresh-token

在过去的几天里,我一直在阅读有关使用刷新和访问令牌进行身份验证的内容,但这是我找不到答案的一件事。假设发送了过期的访问令牌。后端是否应该自动刷新它(如果提供了刷新令牌),或者刷新应该只在刷新端点完成?

作为示例,请考虑以下两个身份验证流程:

自动刷新

  1. 用户使用用户名和密码进行身份验证。API 发回一个包含其数据的短期访问令牌和一个长期刷新令牌。
  2. 对于每个需要身份验证/授权的请求,用户将在请求标头上发送两个令牌。
  3. 如果访问令牌已过期,API 将检查是否发送了有效的刷新令牌、该令牌是否处于活动状态以及它是否与访问令牌属于同一用户。如果一切看起来都不错,那么它将签署一个新的访问令牌并用它更新响应标头。

前端不必担心刷新令牌,但它仍然必须在每次请求后查找响应标头以检查是否发送了新令牌。

手动刷新

  1. 用户使用用户名和密码进行身份验证。API 发回一个包含其数据的短期访问令牌和一个长期刷新令牌。
  2. 对于每个需要身份验证/授权的请求,用户将发送他的访问令牌。
  3. 当访问令牌过期时,用户将其刷新令牌发送到路由refresh/。API 检查令牌是否有效。如果一切正常,它会返回一个新的访问令牌。

每次请求后,客户端都必须检查令牌是否过期,如果过期,则必须执行新请求来刷新令牌。正在向服务器发出更多请求,但另一方面,职责可以更好地分离,因为身份验证路由仅负责处理访问令牌,而刷新令牌处理则位于另一个路由中。

我很难找到有关该主题的资源,因此我不太确定哪种解决方案更好,或者即使我描述的解决方案完全正确。如果我必须选择一个,我会选择自动刷新,因为发出的请求更少,而且客户端可用性看起来更好,但正如我所说,我并不是 100% 同意这一点,因此我正在制作该线程。

访问令牌应该如何刷新?

Gar*_*her 10

在我看来,您在这里缺少一个角色,即授权服务器(AS)的角色:

  • UI重定向到AS以通过密码验证用户
  • AS发出访问令牌和刷新令牌,然后将它们返回给UI
  • UI 使用访问令牌调用 API 一段时间
  • 最终访问令牌过期并且 API 返回 401 响应
  • 然后,UI 调用 AS 并刷新令牌以获取新的访问令牌
  • 然后,UI 使用新的访问令牌重试 API 调用
  • 最终刷新令牌会过期并且刷新尝试将失败
  • 然后,UI 重定向用户以再次登录,然后重复该循环

刷新令牌始终是客户端的责任,并且仅应将访问令牌发送到 API。API 的唯一 OAuth 工作是验证访问令牌并根据其内容进行授权。

您可能有一个 API 正在执行授权服务器的工作。我的目标是分离这些角色。如果有帮助的话,我的消息博客文章显示了来自完整 UI 和 API 解决方案的一些示例消息。


小智 8

我知道 OAuth2 协议的实现使用您在“手动刷新”下描述的流程。客户必须关心自己的清爽度。

客户端可以在每次请求之前检查 access_token 是否仍然有效,或者在由于无效令牌响应而导致请求失败后进行刷新。

access_token 的生命周期很短,因此随每个请求发送它以及被窃听和滥用的风险是有限的。该刷新令牌是长期存在的。如果您在每次请求时都发送refresh_token,攻击者就有更大的机会获得它。

如果您在每个请求中都发送这两种令牌,则不需要区分这两种类型。您只能使用一个长期存在的令牌。


Abd*_* Ch 5

以下是使用自动刷新令牌轮换方案的主要缺点:-

假设客户端同时进行 2 个 API 调用( API A和API B )。在触发这两个 API 调用时,访问令牌已过期。这两个 API 调用都携带相同的过期访问令牌和刷新令牌(假设此刷新令牌有效)。

我们假设API A首先由服务器处理。根据自动刷新方案,服务器将检查API A的访问令牌,如果该令牌已过期,服务器将检查刷新令牌,如果刷新令牌已验证(此刷新令牌也存在于数据库中),服务器将将创建一个新的访问令牌和一个新的刷新令牌(API 附带的刷新令牌将从数据库中删除,并将使用此新的刷新令牌进行更新)。这些新的代币将返回给客户。

API B将遵循相同的流程。但其刷新令牌将无效,因为在处理API A期间,刷新令牌在数据库中被新令牌替换。API B的刷新令牌不存在于数据库中,因此该请求将失败。

如果同时调用多个 API,自动刷新令牌轮换方案将失败,因为第一个 API 请求将在更新令牌时替换刷新令牌,而其余 API 请求将带有刷新令牌,而该刷新令牌不存在于数据库!

我在这里实现了刷新令牌轮换系统。