刷新令牌对服务器性能的影响

发布于 2025-01-15 09:58:18 字数 1095 浏览 3 评论 0原文

我正在寻找一种正确实施刷新和更新的方法。使用 Dotnet Core 后端的简单 SPA 上的访问令牌。我读得越多,我似乎就越担心它对人们的影响 服务器性能,尤其是随着登录用户数量的增长。

拿这个auth0帖子和这个< a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps-05#section-8" rel="nofollow noreferrer">规范 例如,它清楚地表明,由于恶意客户端尝试重用刷新令牌,因此每次创建访问令牌时都需要创建新的刷新令牌。

https: //auth0.com/blog/secure-single-page-applications-with-refresh-token-rotation/

特别是,授权服务器:必须在每次使用时轮换刷新令牌,以便能够在重放时检测到被盗的刷新令牌([oauth-security-topics] 第 4.12 节中所述)

现在假设我们希望保留刷新令牌访问令牌过期时间有限(例如10-20分钟),我们需要保留我们生成的每个刷新令牌,以便识别重复使用旧刷新令牌的恶意活动。

这意味着每 20 分钟就有 n 个用户访问我们的后端来刷新访问令牌并创建新的刷新令牌,因此对于 1k 登录用户来说,每 20 分钟就有 1k 个请求,对于每个用户,我们的 api 检查他们提供的刷新令牌是否已经失效,如果没有,我们会保留新的刷新令牌。

因此,在用户登录一天后,我们保存了:24 * 60 / 20 = 72 个不同的刷新令牌..现在我们对照每个用户检查每个用户?

我错过了什么吗?它是如何扩展的?

I am looking into a way to properly implement refresh & access tokens on a simple SPA with Dotnet Core Backend. The more I read about it the more I seem to worry about its impact on
server performance especially as the number of logged in users grows.

Take this auth0 post and this specification for example it clearly demonstrates that we need to create a new refresh token every time we create an access token, due to Malicious Client attempting to reuse Refresh Token.

https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/

In particular, authorization servers: MUST rotate refresh tokens on each use, in order to be able to detect a stolen refresh token if one is replayed (described in [oauth-security-topics] section 4.12)

Now given that we want to keep the Access token expiry time limited (e.g. 10-20 minutes) and we need to persist every refresh token which we generate in order to recognize malicious activity of old refresh token being reused.

Which means that every 20 minutes n users hit our backend to refresh Access token and create a new refresh token, so for 1k logged in users that`s 1k requests every 20 minutes, also for each of those users our api checks if refresh token they have presented has been already invalidated, if not, we persist the new refresh token.

Hence after a day of user being logged in, we saved: 24 * 60 / 20 = 72 different refresh tokens .. and now we check every user against every single one ??

Am I missing something, how is this scalable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

茶花眉 2025-01-22 09:58:18

实际上,您不需要存储曾经创建的每个刷新令牌。您只需要一份已使用的令牌列表来检查您的用户尝试刷新的令牌是否正在被重用,并且由于您的刷新令牌应该像访问令牌一样有一个到期时间,因此您也不需要存储令牌,即使使用过的,比其使用寿命更长。

  • 如果用户尝试使用有效的刷新令牌:它未过期且不在您使用的令牌列表中。很高兴出发!
  • 如果用户尝试使用过期的令牌:它已过期,因此无需担心重用,无需检查数据库中是否有已使用的令牌。
  • 如果用户尝试重复使用有效的刷新令牌:它在您的列表中。

因此,虽然它确实随着用户数量的增加而扩展,但随着时间的推移,它会保持稳定,并且不会不成比例地膨胀(前提是您确实清除了旧代币)。

还有其他事情需要考虑。正如此 其他 auth0 帖子中所述,在重用的情况下,您希望使整个令牌系列失效,而不仅仅是拒绝重用令牌的一个用户(可能是合法用户)的访问。话又说回来,您不需要存储令牌系列中的每个令牌来跟踪需要失效的内容:您只需向令牌添加一个系列标识符,将该系列标识符本身标记为无效,以防重用,并拒绝未来的刷新尝试(如果它们属于无效系列)。无效系列的列表以及所有失效时间超过刷新令牌寿命的系列标识符都可以被清除。

在服务器请求方面,与 API 密钥或 HTTP 基本身份验证等其他授权方式相比,刷新令牌应该能带来净性能增益,因为对于必须发出的每个刷新令牌,您还会收到相当于 20 分钟的请求您不必查询数据库来检查 API 密钥是否仍然有效,或者提供的密码是否正确(特别是因为像 bcrypt 这样的良好密码哈希函数故意速度很慢)。

You actually don't need to store every refresh token ever made. You only need a list of used tokens to check if the one your user is trying to refresh is being reused, and since your refresh tokens should have an expiry time just like your access tokens, you also don't need to store tokens, even used ones, for longer than their lifespan.

  • If a user tries to use a valid refresh token: It's not expired and not in your used tokens list. Good to go!
  • If a user tries to use an expired token: It's expired so no need to worry about reuse, no need to check your database for used tokens.
  • If a user tries to reuse a valid refresh token: It's in your list.

So while it does scale with the number of users, it's stable over time and won't blow out of proportion (on the condition that you do purge old tokens).

There are other things to consider. As mentioned in this other auth0 post, in case of a reuse, you want to invalidate the whole token family and not just deny access to the one user that reused a token (it might be the legitimate user). Then again, you don't need to store every token from the token family to keep track of what needs to be invalidated: You just need to add a family identifier to your tokens, mark that family identifier itself as invalid in case of a reuse, and deny future refresh attempts if they belong to an invalidated family. The list of invalidated families can be purged as well of all family identifiers invalidated for longer than your refresh tokens lifespan.

On the server request side of things, refresh tokens should be a net performance gain compared to other authorisation means like API keys or HTTP basic authentication, since for every refresh tokens you have to emit, you're also getting 20 minutes worth of requests for which you won't have to query the database to check if the API key is still valid, or if the password provided is the right one (especially since good password hashing functions like bcrypt are slow on purpose).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文