Home > OS >  Impact of Refresh Tokens on server performance
Impact of Refresh Tokens on server performance

Time:04-01

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 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?

CodePudding user response:

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).

  • Related