Search code examples
node.jsjwtjson-web-tokenexpress-jwt

Where jsonwebtoken stored in server nodejs . How to expire JWT once user gets logout


I am storing Tokens on Session/Local storage on the client side.The problem I am facing is once a user copies that token and uses it for other logged-in session services it works but it should return invalid token on JWT.varify.

Is there any way to Blacklist/Delete/Expire currently used token once a user has logged out?


Solution

  • There a a few ways to set up a blacklist for that purpose:

    1) (Blacklist users in the database) Add a database column isTokenExpired for users and set it to false on a successful login, and true when you want to expire the token (for example when the user changes their password, logs out, or enough time has expired).

    The above method will achieve your purpose, but I feel it is an insult to programming. I assume you are using JWT so that the user doesn't have to log in every time, and that you have only 1 server which is doing the authentication and all other server functions. Although JWT was not designed for "sessions", using JWT for this purpose can take load off the database. But if you are then setting and checking another database flag on every user action, you are adding that load again, and you still have all the load associated with the JWT etc, so you might as well just re-auth on every user action.

    2) (Blacklist a user/the token in server RAM) When I researched this problem for myself (how to invalidate individual tokens), I found some solutions where the server maintains either a whitelist or blacklist in RAM, so without adding database or file load. This may be a somewhat better solution, but I can't remember the names of any of the libraries that facilitate this. Maybe someone else can mention some of them.

    3) Set token to a very short expiry time (For example 60 seconds or 5 minutes) and set up the client to automatically request a new token every (~55 seconds or ~4 minutes 50 seconds). The server would then check and validate the token in the same way I assume you are doing it now, without accessing the database, and would then generate a new token with the same values for all the other fields, but with a new "expiry time" value, and send that token back to the client where it would replace its JWT with this new JWT, and re-start its 5-minute timer. This is a good balance between the other choices, and maintains some of the benefits of using the JWT, but does add some small cost. I think this is a pretty good solution for many applications, but it definitely depends on the specific application, but it is somewhat hacky and definitely not "the right way" to do it.

    4) Use JWT + Sessions This is "the right way" to do it. After all my research a long time ago, I realized that JWT's are not designed to be used for maintaining sessions: JWT is only a secure way of representing a claim. Imagine having a large system with tens of millions of users, and you require many servers around the world. You may have 3 authentication servers (in USA, Australia, UK). The user will then send its username and password to an authentication server, where the details will be checked in the database, and if valid it will be sent a JWT. You may then also have 10+ regular servers which handle your API. The client will then make each request to an API server with its JWT. The API server will have a copy of the secret key that was used by the authentication server to generate the JWT, and will validate your claim. Your claim is "I am authenticated". This API server will then generate a session and the client will be "logged in". The JWT may be set to expire after 5 minutes. If the user does not log in within this 5 minutes, they will not be able to log in. If they do, they will be logged in until the API server kicks them out. Whenever something happens that would cause you to want to kick the user, the API server can close the session. Even for a single-server application this is still the right way to do it. JWT are not for sessions, and you (exactly as I did) are starting to notice these seemingly unsolvable problems because you are using JWT for sessions.

    Anyway, I recommend 3 or 4, both of these options have a net-positive value for many applications.

    1 and 2 seem to make more problems than the benefits they provide.

    But of course, it always depends on the application. If you're just making some website on fiverr for $5 then just do whatever, you know what I mean?

    If there's a better solution I'd be interested to know too! Just remember that JWT represents a claim, and consider exactly what claim your client is representing.