1
votes

I'm looking to employ token-based authentication for a mobile app that keeps the user logged in as long as they have not logged out. My approach is to create a JWT refresh token when the user logs in/signs up; This token never expires, and continues to refresh 20 minute access tokens.

The problem arises when they log out. I've read the best way to go about this is to blacklist the JWT on Redis to store revoked keys. However, since the JWT never expires, the record can never be removed from Redis and can start to chunk a lot of my memory.

Should I be worried about this, or is Redis memory-efficient on this respect? Is there a better way to revoke JWT with no expiration?

1

1 Answers

4
votes

A JWT token is a self contained token. That means that it lives on its own until it expires and can't be revoked. So by definition it must expire. Because when it falls into the wrong hands, it'll give access to your resources without being able to revoke it. So yes, you should be worried with this implementation.

The problem here is that you trust the refresh token itself, because it's a JWT. You should in fact trust the server. Not because the JWT can't be trusted, but because the refresh token doesn't have to be a JWT.

Save refresh tokens in memory including the expiration time. You can remove expired tokens from memory. This means that only tokens that exist in memory can be used to request a new access token. And to be on the safe side, use one-time only refresh tokens.

The flow would be something like this:

  1. the user logs in, receives a JWT access token (5 minutes) and the refresh token 1 code (48 hours). Refresh token 1 is saved on the server.
  2. five minutes later: the access token expires
  3. a new access token is requested using refresh token 1.
  4. user receives a new access token (5 minutes) AND the refresh token 2 code (48 hours). Token 1 is removed from memory and token 2 is added to memory.
  5. and this goes on for several hours.
  6. For two days the user doesn't use the app
  7. 50 hours later: because both tokens are expired, the user has to login again. Resetting the flow.

On logout remove the refresh token from memory. And if in the meantime you wish to revoke access. Simply remove the refresh token from memory. Within 5 minutes the user has to login again.