访问令牌应该自动刷新还是手动刷新?
Should access tokens be refreshed automatically or manually?
在过去的几天里,我一直在阅读有关使用刷新和访问令牌进行身份验证的内容,但这是我找不到答案的一件事。假设发送了一个过期的访问令牌。后端应该自动刷新它(如果提供了刷新令牌),还是应该只在刷新端点进行刷新?
例如,考虑以下两个身份验证流程:
自动刷新
- 用户使用用户名和密码进行身份验证。 API 发回一个包含他的数据的短期访问令牌,以及一个长期存在的刷新令牌。
- 对于每个需要 authentication/authorization 的请求,用户将在请求中发送两个令牌 headers。
- 如果访问令牌过期,API 将检查是否发送了有效的刷新令牌、它是否处于活动状态以及它是否与访问令牌属于同一用户。如果一切正常,那么它将签署一个新的访问令牌并用它更新响应 headers。
Front-end 不必担心刷新令牌,但它仍然需要在每次请求后查找响应 headers 以检查是否发送了新令牌。
手动刷新
- 用户使用用户名和密码进行身份验证。 API 发回一个包含他的数据的短期访问令牌,以及一个长期存在的刷新令牌。
- 对于每个需要 authentication/authorization 的请求,用户将发送他的访问令牌。
- 当访问令牌过期时,用户会将他的刷新令牌发送到
refresh/
路由。 API 检查令牌是否有效。如果一切正常,它 returns 一个新的访问令牌。
每次请求后,客户端必须检查令牌是否过期,如果过期则必须执行新请求以刷新令牌。正在向服务器发出更多请求,但另一方面,职责分离得更好,因为 auth 路由仅负责处理访问令牌,而刷新令牌处理位于另一条路由中。
我很难找到关于这个主题的资源,所以我不太确定哪个解决方案更好,或者即使我描述的解决方案完全正确。如果我必须选择一个,我会选择自动刷新,因为发出的请求更少,而且客户端的可用性看起来更好,但正如我所说,我不是 100% 这样做,因此我正在制作那个线程.
应该如何刷新访问令牌?
我的经验是 OAuth2 access_token 请求不喜欢额外的数据,这意味着您将无法同时发送 access_token 和 refresh_token。这将导致您描述为唯一选项的手动刷新方案
我知道的 OAuth2 协议的实现使用您在“手动刷新”下描述的流程。刷新需要客户自理
客户端可以在每次请求之前检查 access_token 是否仍然有效,或者在由于无效令牌响应导致请求失败后进行刷新。
access_token 的生命周期很短,因此随每个请求发送它并被窃听和滥用的风险是有限的。 refresh_token 是长寿的。如果您在每次请求时都发送 refresh_token,攻击者获得它的机会就会大得多。
如果您在每次请求时都发送这两种令牌,则不需要区分这两种类型。您将只使用一个长期存在的令牌。
我觉得您在这里缺少一个角色,即授权服务器 (AS) 的角色:
- UI 重定向到 AS 通过密码验证用户
- AS 颁发访问令牌和刷新令牌,然后 returns 将它们发送到 UI
- UI 使用访问令牌
调用 API 一段时间
- 最终访问令牌过期并且 API returns 401 响应
- 然后 UI 使用刷新令牌调用 AS 以获取新的访问令牌
- 然后 UI 使用新的访问令牌重试 API 调用
- 刷新令牌最终会过期,刷新尝试将失败
- 然后 UI 重定向用户重新登录并重复循环
刷新令牌始终是客户端的责任,并且只应将访问令牌发送到 API。 API 唯一的 OAuth 工作是验证访问令牌并根据其内容进行授权。
您可能有一个 API 正在执行授权服务器的工作。我的目标是将这些角色分开。如果有帮助,我的 Messages Blog Post 在完整的 UI 和 API 解决方案中提供了很多关于消息的详细信息。
在过去的几天里,我一直在阅读有关使用刷新和访问令牌进行身份验证的内容,但这是我找不到答案的一件事。假设发送了一个过期的访问令牌。后端应该自动刷新它(如果提供了刷新令牌),还是应该只在刷新端点进行刷新?
例如,考虑以下两个身份验证流程:
自动刷新
- 用户使用用户名和密码进行身份验证。 API 发回一个包含他的数据的短期访问令牌,以及一个长期存在的刷新令牌。
- 对于每个需要 authentication/authorization 的请求,用户将在请求中发送两个令牌 headers。
- 如果访问令牌过期,API 将检查是否发送了有效的刷新令牌、它是否处于活动状态以及它是否与访问令牌属于同一用户。如果一切正常,那么它将签署一个新的访问令牌并用它更新响应 headers。
Front-end 不必担心刷新令牌,但它仍然需要在每次请求后查找响应 headers 以检查是否发送了新令牌。
手动刷新
- 用户使用用户名和密码进行身份验证。 API 发回一个包含他的数据的短期访问令牌,以及一个长期存在的刷新令牌。
- 对于每个需要 authentication/authorization 的请求,用户将发送他的访问令牌。
- 当访问令牌过期时,用户会将他的刷新令牌发送到
refresh/
路由。 API 检查令牌是否有效。如果一切正常,它 returns 一个新的访问令牌。
每次请求后,客户端必须检查令牌是否过期,如果过期则必须执行新请求以刷新令牌。正在向服务器发出更多请求,但另一方面,职责分离得更好,因为 auth 路由仅负责处理访问令牌,而刷新令牌处理位于另一条路由中。
我很难找到关于这个主题的资源,所以我不太确定哪个解决方案更好,或者即使我描述的解决方案完全正确。如果我必须选择一个,我会选择自动刷新,因为发出的请求更少,而且客户端的可用性看起来更好,但正如我所说,我不是 100% 这样做,因此我正在制作那个线程.
应该如何刷新访问令牌?
我的经验是 OAuth2 access_token 请求不喜欢额外的数据,这意味着您将无法同时发送 access_token 和 refresh_token。这将导致您描述为唯一选项的手动刷新方案
我知道的 OAuth2 协议的实现使用您在“手动刷新”下描述的流程。刷新需要客户自理
客户端可以在每次请求之前检查 access_token 是否仍然有效,或者在由于无效令牌响应导致请求失败后进行刷新。
access_token 的生命周期很短,因此随每个请求发送它并被窃听和滥用的风险是有限的。 refresh_token 是长寿的。如果您在每次请求时都发送 refresh_token,攻击者获得它的机会就会大得多。
如果您在每次请求时都发送这两种令牌,则不需要区分这两种类型。您将只使用一个长期存在的令牌。
我觉得您在这里缺少一个角色,即授权服务器 (AS) 的角色:
- UI 重定向到 AS 通过密码验证用户
- AS 颁发访问令牌和刷新令牌,然后 returns 将它们发送到 UI
- UI 使用访问令牌 调用 API 一段时间
- 最终访问令牌过期并且 API returns 401 响应
- 然后 UI 使用刷新令牌调用 AS 以获取新的访问令牌
- 然后 UI 使用新的访问令牌重试 API 调用
- 刷新令牌最终会过期,刷新尝试将失败
- 然后 UI 重定向用户重新登录并重复循环
刷新令牌始终是客户端的责任,并且只应将访问令牌发送到 API。 API 唯一的 OAuth 工作是验证访问令牌并根据其内容进行授权。
您可能有一个 API 正在执行授权服务器的工作。我的目标是将这些角色分开。如果有帮助,我的 Messages Blog Post 在完整的 UI 和 API 解决方案中提供了很多关于消息的详细信息。