如何保护刷新令牌?

问题描述 投票:0回答:5

我正在使用JWT来验证我的应用程序的用户。当用户登录时,他们将获得访问令牌和刷新令牌。为了保证刷新令牌的安全,我不会将其存储在客户端,而是将其保存在后端并使用其帐户,因此不容易访问。我对刷新令牌的安全性感到困惑,这是我在阅读有关如何使用刷新令牌的在线资源时所理解的逻辑:

  1. 认证
  2. 在某处存储访问令牌+刷新令牌(在我的情况下,在前端访问令牌并在后端刷新令牌)
  3. 执行api请求时,验证api端的访问令牌
  4. 如果访问令牌已过期,请使用刷新令牌生成新的访问令牌+新刷新令牌,将访问令牌发送回客户端
  5. 像以前一样存储令牌......并重复

我担心的安全问题是,如果其他人(黑客)获得了访问令牌,并且他们向api发送请求,如果令牌过期,api将使用刷新令牌获取新访问权限令牌+新刷新令牌并至少将访问令牌返回给黑客。

我读了大约5-6次this文章,我读了几次this文章,以及关于这个主题的其他一些文章,他们都说了一些关于

确保安全地存储刷新令牌,因为它很长时间,access_token是短暂的,所以没有那么大的交易

但是根据我上面描述的流程,访问令牌是否短暂并不重要,刷新令牌将用于获取新的访问令牌并永久访问。

有什么我想念的吗?如果黑客获得过期的访问令牌,api将如何知道谁发送请求?它仍然会使用刷新令牌发送一个新的。我应该以某种方式验证谁发送请求?


UPDATE

所以我确实理解当请求新的访问令牌时,我需要通过刷新令牌,客户端ID和客户端密钥发送。我遇到的问题是,像以前一样,黑客可以向我的API服务器发送请求,服务器从黑客获取被劫持的访问令牌,它会看到它已过期,因此它将发送刷新令牌,以及客户端ID /客户端密钥(存储为环境变量)到Auth API并获取新的访问令牌/刷新令牌,这使我们回到同样的问题。


更新2

关于这个问题的一些有趣问题:

  1. Why Does OAuth v2 Have Both Access and Refresh Tokens?
  2. https://security.stackexchange.com/questions/87119/how-secure-are-expiring-tokens-and-refresh-tokens

根据第二个问题和答案,似乎刷新令牌不是一种更安全的维护访问方式,只是因为更容易检测到黑客,因为身份验证/刷新令牌不断被请求并使其他令牌无效。这个问题是只有当2个用户同时尝试访问资源时才会发生这种情况 - 如果只有黑客在给定时间段内处于活动状态,他将无限制地访问原始用户数据,直到原始用户尝试使用应用程序和访问受保护的资源

oauth-2.0 access-token refresh-token
5个回答
1
投票

您不应将令牌存储在服务器上。客户端验证并获取令牌。您可以将令牌存储在cookie或localStorage中的浏览器中。每个请求都使用令牌授权。如果您通过未加密的频道发送它而没有ssl,则可以截获。获取令牌的黑客确实允许他们冒充用户。过期的令牌不应允许重新身份验证,而无需再次重新输入用户凭据。过期的令牌应该被忽略。


0
投票

在您链接的第二篇文章中,据说要刷新令牌,您必须发布刷新令牌和client_id以及client_secret,因此基本上您在刷新访问令牌时重新验证用户身份。

要使用刷新令牌,请使用grant_type = refresh_token向服务的令牌端点发出POST请求,并包括刷新令牌以及客户端凭据。


0
投票

如果要在服务器上存储刷新令牌,则服务器应在身份验证响应中包含安全会话cookie以标识用户。您可以通过使用HttpOnly标志设置cookie来防止攻击者提取安全会话cookie。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Secure_and_HttpOnly_cookies

cookie不是刷新令牌。这将是一些其他类型的会话cookie。不向用户返回刷新令牌的一个应用程序流是单页面应用程序流。

https://auth0.com/docs/flows/concepts/single-page-login-flow

在此流程中,令牌刷新通过“无声身份验证”完成。

https://auth0.com/docs/api-auth/tutorials/silent-authentication#initiate-a-silent-authentication-request

如果用户已在Auth0中拥有有效会话且无需同意或其他提示,则验证响应成功。

所以我们需要通过存储一些用户标识符来维护会话。


0
投票

访问令牌和刷新令牌的用途如下:

  1. 在用户登录时生成过期访问和刷新令牌并发送到前端应用程序(Android,IOS,Web App)。
  2. 前端应用程序在其数据库中安全存储刷新令牌。
  3. 前端应用程序向每个请求发送访问令牌,JWT在不命中数据库的情况下对其进行验证。
  4. 身份验证适用于访问令牌的定义时间。
  5. 当它到期时,前端应用程序会向您的服务器发送刷新令牌,另外您使用JWT验证它并在数据库中检查它是否相等。
  6. 服务器生成新的访问令牌等。

PS:整个通信应该通过HTTPS进行。

我有基于上述逻辑的实现,访问令牌每30分钟到期,刷新令牌有效年份。

使用数据库验证刷新令牌的事情是您可以控制用户登录过程,并且您可以限制能够使用相同帐户的应用程序的设备数量。

只要用户再次发送登录请求,您只需更新服务器上的刷新令牌即可。


0
投票

有一个很好的文档OAuth 2.0 for Browser-Based Apps讨论了这些应用程序的最佳实践。

我会选择在客户端或服务器上保留令牌。将它混合(在服务器上保留刷新令牌并在浏览器中访问令牌),您可以创建自己的漏洞并使用自己的漏洞。

如果浏览器应用程序仅需要访问令牌来访问其后端,您可以考虑将后端用作OAuth2客户端(接收授权代码),获取用户的身份,发出cookie以维护浏览器和浏览器之间的会话后端。它比交换,刷新和验证OAuth2令牌容易得多。

如果您确实希望将浏览器应用程序保留为接收令牌的OAuth2客户端,则应使用PKCE extension(因此保留在网络缓存中的身份验证代码和浏览器历史记录不能用于获取令牌)并获取每个新访问权限的新刷新令牌令牌 - 看看chapter about refresh tokens

授权服务器不应该向基于浏览器的应用程序发出刷新令牌。

如果授权服务器确实选择向基于浏览器的应用程序发出刷新令牌,那么它必须为每个访问令牌刷新响应发出一个新的刷新令牌。这样做可以降低泄漏刷新令牌的风险,因为如果攻击者和合法客户端都尝试使用相同的刷新令牌,则可以检测到泄漏的刷新令牌。

您的浏览器应用程序可以在sessionStorage中保留其令牌以使页面重新加载。


0
投票

基本上,使用基于浏览器的应用程序的刷新令牌似乎是一个坏主意。刷新令牌适用于移动应用程序,其中刷新令牌可以安全地存储在手机上 - 手机具有某种安全存储机制,而浏览器则没有。

© www.soinside.com 2019 - 2024. All rights reserved.