DEV Community

Discussion on: JSON web tokens are NOT meant for authenticating the same user repeatedly: Use session tokens instead

Collapse
 
siddhantk232 profile image
Siddhant Kumar

To revoke a JWT, you can change the secret you used to sign those tokens, this invalidates all the tokens you issued. This works like a master reset for you service in case your tokens got compromised.

Also, when signing a token, using a version identifier in token's data can be useful whenever you want to revoke this token for a specific user. So if a user "forgets his password" or logs out, you can change the version identifier in the DB. Now, if the user tries to log in with his old JWT, you will know as the version of his JWT and version stored in DB are not the same.

This is my understanding of using JWTs for web authentication but I totally see the point of using sessions. In most cases I also prefer to use sessions but knowing how to solve the problem of invalidating JWTs is still helpful.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

I just had an "Aha" moment. Thanks!

Collapse
 
samjakob profile image
Sam (NBTX)

Doesn’t setting a version on the JWT invalidate the point of JWTs because at that point you still have to do the lookup every time the JWT is used to make sure it’s valid?

Collapse
 
siddhantk232 profile image
Siddhant Kumar

To be honest, I do not have a proper answer to this. You are right, I do have to talk to a DB every time to verify a JWT. This is also the case in session-based authentication where you check the session to see if the user is authenticated.

Now the possible solution I can think of, based on my recent readings, is:

You implement a refresh_token, save it in the client as a strict samesite, httponly cookie with a specific path on your server so that this cookie is not sent with every request. Then on your server, you can version this refresh_token instead of the acces_token and can invalidate refresh tokens by changing the versions. This approach should have the access_token to be short-lived. So even if your access_token is compromised (highly unlikely) it will be only valid for a short period of time. Again, this is similar to session-based auth but with this, you are completely stateless with your aceess_token, that is this access_token can be verified without any DB calls until it is expired. When the access_token expires, you request a new one using the refresh_token.

If you are using asymmetric JWTs, then you can also share this access_token with other services without sharing the signing secret and they can verify if the token is published by a trusted source. One way to do this is by using JWK(S).

This is how I think OAuth also works. The issuer (aka authentication server) first authenticates you and manages your session on their servers. Then, you can request an access_token and refresh_token (depends on the grant type). When you have the access_token, you can share this token with relevant services that know how to verify this token.

I do not know if this is the best answer and I am not sure how I feel about giving access for a short period of time even if I have revoked the refresh_token but I have read about people using this approach. So, in the end, you are making DB calls but they are not on every request, you make DB calls only when the acess_token expires.

I hope this makes sense.

Thread Thread
 
samjakob profile image
Sam (NBTX)

Gotcha! That all makes sense and I understand the approach but really this is my sorta quandary when it comes to JWTs, like you said:

I do not know if this is the best answer and I am not sure how I feel about giving access for a short period of time even if I have revoked the refresh_token but I have read about people using this approach. So, in the end, you are making DB calls but they are not on every request, you make DB calls only when the acess_token expires.

I feel like it ends up being essentially a glorified session token simply because the access period is so low you might as well just check it on every request. (The idea of having it available for a short period after revocation - no matter how long - really doesn’t sit well.)

I feel like there’s a use case for JWT but it certainly isn’t a be-all-end-all to simply replace the session token in all cases.

Collapse
 
rihan profile image
Rihan

Including a version is something I've never thought of and will change my life, thanks!

Collapse
 
blackr1234 profile image
blackr1234

You don't have to add a version number as one of the JWT claims. You can simply check if the issued-at value is before the updated-at value of your user record. If it is, that means the user record has been updated after the token is issued, so the user should login again to get a new token.