5 ms·
> For the most simple use case of an client auth state; you want to be able to revoke auth straight away if an account is compromised. This means you have to ch
by hn_throwaway_99 1y ago
> For the most simple use case of an client auth state; you want to be able to revoke auth straight away if an account is compromised. This means you have to check the auth database for every request anyway, and you probably could have got whatever else was in the claim there quickly.
FWIW, I built a system previously that got around this "having to check the DB on every access to check for revocations" issue that worked quite well. Two important things to realize:
1. Revocations (or what is usually basically "explicit logout") is actually quite rare in a lot of user application patterns. E.g. for many web apps users very rarely explicitly logout. It's even rarer for mobile apps.
2. You only need to keep around a list of revocations for as long as your token expiry is. For example, if your token expiration is 30 mins, and you expire a user's tokens at noon, by 12:30 PM you can drop that revocation statement, because any tokens affected by that revocation would have expired anyway.
Thus, if you have a relatively short token expiration (say, a half hour), the size of your token expiration list can almost always fit in memory. So what I built:
1. The interface to see if a token has expired is basically "getEarliestTokenIssuedAt(userId: string): Date" - essentially, what is the earliest possible issuance timestamp for a token for a particular user to be considered valid. So, revoking a user's previously issued tokens means just setting this date to Now(), then any token issued before that will be considered invalid.
2. I had a table in postgres that just stored the user ID and earliest valid token date. However, I used postgres' NOTIFY functionality to send a broadcast to all my servers whenever a row was added to this table.
3. My servers then just had what was a local copy of this table, but stored in memory. Again, remember that I could just drop entries that were older than the longest token expiration date, so this could fit in memory.
On the off-chance that somehow the current revocation list couldn't fit in memory, I build something in the system that allowed it to essentially say "memory is full" which would cause it to make a call back to postgres', but again, that situation would naturally clear up after a few minutes if revocations went back down and the token expiration window passed.
This sounds more complicated than it actually was. It has the benefits of:
1. Almost no statefulness, which was great for scalability.
2. Verifying a token could still always be done in memory, at least almost. Over a couple years of running the system I actually never hit a state when the in-memory revocation list got too big.
- vintermann 1y ago> You only need to keep around a list of revocations for as long as your token expiry is. For example, if your token expiration is 30 mins, and you expire a user's tokens at noon, by 12:30 PM you can drop that revocation statement, because any tokens affected by that revocation would have expired anyway. And this sort of thing is basically what redis is for, right? Spin up a docker container, use it as a simple key value store (really just key store). When someone manually invalidates a token, push it in, with the expiry date is has anyway.
- bandoti 1y agoMight not even need to store the token itself just a piece of data that is contained in the claims to say the account is in a good state. Any number of tokens then can be issued and the validation step would ensure the claims is correct.
- fmbb 1y agoWhat you describe sounds like it will make any explicit log out action users do on any device turn into a ”log me out from all devices” action, which was probably not at all the user’s intent unless that is the only explicit option you give them.
- littlecranky67 1y agoA "logout" action from the user should just delete the JWT from the device he is using. Asuming the token wasn't compromised, there is no backend work involved. Is this as secure as doing a blacklist for non-expired tokens? No, it isn't. It is a sane tradeoff between decent security and implementation complexity.
- orphea 1y ago> A "logout" action from the user should just delete the JWT from the device he is using. I wouldn't say should. It may. If you're fine with inability to terminate sessions on other devices.