Issue
I have been using Flask and JWT to create authentication on my backend. Creating and using access tokens is simple enough, but I've run into some conceptual misunderstanding when trying to discover how to handle the usage and storage of refresh tokens.
Upon initial login, I distribute an access token (with 10 minute expiry) and a refresh token (with 4 day expiry). The 'jti' attribute of the refresh token is stored in a table on the database, along with its expiry date. The access token is stored in memory, and the refresh token is stored in HttpOnly cookies. When the access token expires, a "silent refresh" is sent to the backend with the refresh token. It is first checked for validity (user ID matches up, signed correctly, and is not expired), and then the database is checked to see if it contains that specific refresh token's 'jti'. If it does, then that refresh token is deleted from the database (and can therefore no longer be used) and a new access token and refresh token are sent to the user. This allows for the refresh tokens to only be single use. However, if a user logs out and logs back in repetitively, the refresh token cookie in their browser keeps getting overwritten with a new value (which is fine), but the database now contains a ton of references to "unused" refresh tokens. I'm not sure if my understanding of the JWT workflow is completely incorrect, or if this is normal.
I mainly conceptually followed this guide. Is this repetitive logging in and getting refresh tokens normal? I don't see how to manually find and remove older (but still valid) tokens that are used in the same browser.
Solution
Your implementation looks fine. It's normal that you issue new tokens for a new session. I think there are two solutions to your problem:
Add a
expiration
column to your table with refresh tokens. Then you will be able to remove stalejti
s from the table once they're expired.Instead of keeping information about issued refresh tokens, you can keep information about used refreshed tokens. So, when you issue the token you don't save it in the DB. When the user uses the RT, you can save the
jti
andexpiration
in the DB. Whenever a RT is used you check whether thejti
is in the DB. If it is, you decline the request. You can remove entries from this table after expiration, as you verify expiration on the RT anyway.
Answered By - Michal Trojanowski
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.