Hacker News new | ask | show | jobs
by Freak_NL 3384 days ago
Session invalidation is possible though, by maintaining a (short) blacklist of tokens on the server. JSON Web Tokens can be given an ID (via the jti claim), and server-side these IDs can be matched against this blacklist. When you log out, you send a request to the service that your current token be blacklisted.

Because JSON Web Tokens are short-lived, the blacklist need only contain tokens valid for validity period plus a few seconds and remains very small (often empty).

If you use JWT to allow authorization on several server, then you do need to distribute this blacklist, so it is not a completely trivial solution. In the simplest scenario you might suffice with only maintaining a blacklist on the server that can refresh tokens (this means that when the token expires, a new one cannot be automatically acquired).

1 comments

Yeah, and that's kinda sad because now you have to check a signature AND query a database!
s/database/in-memory-map/g should be fine - and suddenly it's pretty lightweight (subtracting service restarts and a highly available message bus of course :)
s/in-memory-map/cache-server/g if you happen to have a load balancer without sticky session.
In both cases there is a DB somewhere storing the list. The difference is that with the blacklist the server can keep an in-memory cache because it's so small. Sessions don't need to be invalidated atomically so the blacklist can be refreshed every couple of seconds.
Store it in a DB for persistence, but push it out to application memory. If for some reason you expect your blacklist to be very large (maybe, you have a massively popular API?), push a bloom filter of the blacklist instead of the actual list.

Now, you (probably) only absorb the DB hit on blacklisted tokens.

Two solutions:

1. As other posters pointed out. The blacklist is probably pretty small and can live in memory on your apps servers. If you have a distributed raft network or something to keep it in sync across nodes, even better.

2. You can avoid checking it against the DB unless the API call is sensitive (example: modifies data).

Yeah, of course you can do these things. I really meant to say, "there now exists server-side state for this" — I'm bothered by how existence of that state defeats the statelessness benefits of signature-based schemes, not the fact that I have to query a remote database.

Oh, and also: "only store a blacklist" does not work if you want to provide the "revoke this app you gave access to a while ago and now it's spamming" functionality like in most social networks.

Well you cache the blacklist and push updates, so it has no real performance cost. Just a tad more dev time