DEV Community

JWT can fit as an authentication system with a blacklist technique

Rakan on February 04, 2024

As mentioned before, JWT has some drawbacks that make it unsuitable as an authentication system. However, there are ways to work around these drawb...
Collapse
 
ryansgi profile image
Ryan B

One thing that you could do instead of using a cron is to use database triggers; something like:
CREATE TRIGGER delete_blacklist_rows_trigger AFTER SELECT ON blacklist EXECUTE FUNCTION delete_expired_rows();

Collapse
 
dagnelies profile image
Arnaud Dagnelies

If I logout on my pc, I don't necessarily want to be logged out as well on my phone or tablet. Yet, this is exactly what your "solution" does. It kills all sessions on all devices at once, since all tokens having been issued before the logout are invalidated... And it does not even touch the issue of refresh tokens.

Collapse
 
irakan profile image
Rakan

No, you need the JWT payload to have device info or any other info you want.. and check against that. For example, Kill the token that has device “mobile” for user “123”

Collapse
 
dagnelies profile image
Arnaud Dagnelies

Well, you certainly could add a plaform or device to your JWT blacklist to do some "browser fingerprinting" but of course this has its limits. I'm not even sure you could reliably distinguish between a user's phone and tablet using the same OS/browser, or between a PC and a Laptop using same OS/Browser. Blacklisting one with minimum_issued_at is likely to kill the other session too ...or you'll need to put a lot of extra work. Last but not least this nullifies the main benefit of using JWTs, namely to avoid DB lookups.

Thread Thread
 
irakan profile image
Rakan

its not “alot” of extra work.. whenever you create the JWT token for the user just add the fields in JWT payload you want to check against such as device, user_agant, location.. and whatever else you want, the sky is the limit.

JWT definitely was not designed to have DB lookup as I mentioned in the post, but the DB table here will be very small since it will only have invalid tokens when user logs out/blocked and will be cleaned periodically. This is a work around for my drawbacks that were mentioned in my previous post.

JWT is just a tool like many tools out there, take it into your advantage as you need.

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix

What is the use case of blacklisting tokens?
Why not just let them expire naturally?
If you have high security requirements (like a bank) -> you have/use 2fa anyway.

Collapse
 
ryansgi profile image
Ryan B • Edited

Generally if you log out with a JWT, most of the time what will happen is you will remove the token from local storage/cookies. Let's say you have an authentication strategy where you're not using refresh tokens (which I recommend you should do), but long lived JWTs such as 1 DAY, 5 DAY, 30 DAY etc. So, if a user "logs out", the user may believe they are logged out but the JWT is technically still usable. By adding them to a blacklist, you have a mechanism to block any further usage of the JWT. Further, you can use the tokens minimum_issued_at to expire the row in your postgres/redis/store after the JWT will have expired and become unusable.

Another good example of being able to blacklist tokens is it provides a mechanism to provide user functionality such as "Force logout on devices" that you might see on things like Gmail and so forth.

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix

Isn't this very rare (purely theoretical) use case?

If you delete the JWT from users device memory and storage ->
How does someone use a "technically still usable" token if its nowhere to be found?

I assume

  • you have protection against XSS and CSRF in place, which you need either way
  • you generate a individual token for each device you log into -> so even if you share the link the user still has to re-login
Thread Thread
 
ryansgi profile image
Ryan B

It boils down to a principle I adopted a long time ago: Never trust user input.

Collapse
 
dagnelies profile image
Arnaud Dagnelies

You also confuse HTTP codes. 403 is when you are authenticated but access to the resource is forbidden because of insufficient rights. When you are logged out, you become 401 Unauthorized.

Collapse
 
irakan profile image
Rakan

Since its a blacklist I choose 403 :)