I am currently building a Node.js application and trying to use JWT to handle sessions. In every implementation that I've seen the refresh-token
is stored in a fast database like redis
. When the token has expired, the client sends the refresh-token
to get the new access-token
, then the server checks if the refresh-token
is in the database, then generates a new token.
But since the refresh-token
must be generated by the server, cannot be tampered with, and we can also check if it has expired, why do we need to store it. If it is for logout
then can't we just store the user_id
in the database for the people who have been logged in without storing the refresh-token
.
I was also thinking along the lines of storing the newest access-token
instead of refresh-token
in redis
as value for the user_id
. The reason being that we will generate a new access-token
only when the previous one has expired. So the following scenario cannot happen,
- User logs in, gets
access-token
andrefresh-token
. - Immediately refreshes their token while the previous one is still valid.
- Logs out, and uses their old access token.
Since most implementations blacklist only the access-token
provided by the client during logout, I believe this scenario can be possible if the REST API is used by the client.
So what is the use of storing the refresh-token
, and would storing the access-token
instead be beneficial in any way. Some more information regarding the application,
- I am using
redis
for logged in users, and blacklistedaccess-token
(provided during logout). - I am storing both
refresh
andaccess
tokens in httpOnly cookies, and sendingaccess
tokens as bearer tokens. refresh-token
is sent in POST body while refreshing the access token.- I am not using
https
CodePudding user response:
Let me answer each of your questions:
- "But since the
refresh-token
must be generated by the server, cannot be tampered with, and we can also check if it has expired, why do we need to store it":
Refresh tokens are meant to have very long expiration times (possibly months), so that users do not have to log into the application frequently (especially in the case of mobile applications). Therefore, if a malicious person steals a user's refresh token, the user's protected information will be exposed for a long time. In case this happens, a considerably secure application should have mechanisms to, for example, detect sudden changes in the IP address of its users and report them. Now, if a user confirms the existence of strange behavior in his account, it is necessary to revoke all his refresh tokens to protect his information, and to do this, it is necessary to have control of the refresh tokens that a certain user has, so they have to be stored.
- "If it is for
logout
then can't we just store theuser_id
in the database for the people who have been logged in without storing therefresh-token
":
You need to store both, both the "user_id" and the refresh tokens, in such a way that you can have a control of all the refresh tokens of a certain "user_id" (as stated above). If you only want to store the "user_id" of the logged in users (without storing refresh tokens), I don't know how you will check if a user is authorized to renew an access token without having to make the user log in.
- "I was also thinking along the lines of storing the newest
access-token
instead ofrefresh-token
...":
- By doing this you are losing advantages of the "stateless" approach offered by JWTs (https://restfulapi.net/statelessness), since you are storing a state of them. If you really want something like this, it's probably best to use a "stateful" approach like sessions.
- I don't see the reason to do this. Suppose you have a web application and a mobile application connected to a RESTful API, if the user logs into both applications he will have multiple valid access tokens and refresh tokens, so it is perfectly normal for a user to have multiple valid tokens at the same time.
- If a user logs out, simply remove the access token and the refresh token from his device, additionally, remove the refresh token from the database. Use short expiration times on access tokens (15 minutes is very common), and so you have no need to store them as they will expire quickly. That's it.