SECRET OF CSS

3 Scenarios Where You Can Store JWT Token in Your DB | by Aindrila Choudhuri | Jul, 2022


Know when and why

0*YaN KB UHJJb9o90
Photo by Kelly Sikkema on Unsplash

Token-based authentication (most often JWT based) is referred to as stateless authentication — because the authentication server doesn’t need to maintain any state, the token itself contains all the necessary information to verify a token bearer’s authentication.

The server can seamlessly check whether the JWT contains the necessary information about the user’s identity and authorization to perform an action without querying the database. Now the question arises, if such is the scenario then do we need to save the JWT token in the database? If yes, then when and why?

I will try to cover three scenarios where the necessity to save the tokens in DB arises.

Before we dive deep into the topic let me give you a tiny introduction on access tokens and refresh tokens. When a user logs in, the authorization server issues an access token (generally JWT), then the client can use this token to make secure API calls.

When the client needs to access any protected resource from the server on behalf of a user, it attaches the token in the request header which helps the server to determine the authenticity of the client/user. Access tokens have a very short lifespan (generally not more than 30mins).

Once the access token expires the client application can prompt the user to re-login (which is certainly not a good user experience) or the client can use a refresh token which is issued by the authorization/authentication server to generate a new access token.

Refresh tokens generally have a much higher life span than the access tokens. They may or may not be JWT. Refresh tokens can be a simple encoded string or a UUID. Refresh tokens are also bearer tokens, hence ​malicious users can theoretically steal the refresh token and use it indefinitely to access protected resources from the server. Then how do we secure our application from malicious users accessing protected resources?

The most straightforward answer to this question would be saving refresh tokens in the database and revoking access of all users by deleting all the refresh tokens when any such malicious behavior is reported. But what if it’s not reported, do we let the malicious user access protected resources indefinitely? Do we keep on saving refresh tokens in our database?

The answer to this question is refresh token rotation, refresh token reuse detection and deleting all old refresh tokens when a new one is generated. Let me try to explain my answer — when a new access token is generated (at the time of sign in/signup or using a refresh token) — a new refresh token should also be generated (this is called refresh token rotation), and all the previous refresh tokens must be deleted.

In this way — even if a malicious user steals the refresh token, when the legitimate user tries to log in to the application, a new access token and a new refresh token will be generated, and all other refresh tokens will be deleted, if the malicious user tries to use the old refresh token the refresh token reuse detection would already detect the reuse or the refresh token wouldn’t exist in DB. This way we can prevent a malicious attack.

A verification email is sent out to a user email address (which he/she uses to register), after they register into an application. This email contains a link with a token generated by the server for that user ID, when the user clicks on the link an API request is made to the server with this token (email verification token). These tokens always have a short expiration time.

The server needs to verify this token for that user email. But what if the user clicks on the resend verification email again even before the current link/token’s expiration? To handle such scenarios tokens need to be saved in DB — either all the tokens or only the latest one (when a new token is generated old tokens are deleted).

Since all or more than one token is active at this moment, JWT verification would pass for any of the tokens, but we should compare only with the latest one. Once verification is done, all the email verification tokens for that user must be deleted.

When a user clicks on forgot-password and enters his/her email address, an email is sent out to the user containing a link (which contains a reset password token). These reset password tokens also generally have a short lifespan.

Once a user clicks on the link, he/she needs to enter the new password, and once clicked on reset password an API request is made to the server containing the new password and token sent in the email link. The reason to save/not save this token is pretty similar to email-verification-token. If the user clicks on the forget password more than once and receives multiple emails (all before the token’s expiry).

In this case, we need to store all the tokens in DB or the latest one (when a new token is generated the old tokens should be deleted). After a user clicks on the link, the token in the API request payload is matched with the latest token in DB for that user, and all the reset-password tokens for that user must be deleted.

JWT allows the server to perform stateless authentication by checking the token content. If in any case more than one JWT can be generated for a user for a single purpose like an email verification token, or reset password token in those cases we must save the tokens/latest token in DB to match with the most recent one. Similarly, in case of refresh token (JWT or not) — we need to save it in DB to revoke and prevent malicious user access.

Code, read, and change the world!



News Credit

%d bloggers like this: