3 ms·
In sessions vs. JWT revocation lists, there is an argument in favor of JWT revocation lists. JWTs have a limited expiry timestamp, so you only ever need to main
by littlecranky67 4mo ago
In sessions vs. JWT revocation lists, there is an argument in favor of JWT revocation lists. JWTs have a limited expiry timestamp, so you only ever need to maintain a revocation list for tokens not expired yet. Given that you probably only have a fraction of JWTs revoked compare to valid JWTs in circulation, you only need to query a very small dataset for each request.
When using sessions, your list of valid sessions is probably orders of magnitudes higher that the revocation list - thus the data lookup costs and the storage cost of that statefulness is higher.
Plus, the article mentions JWTs are stateless but that is usually not true. You mostly not only validate the JWT, but also obtain a matching identity object (i.e. user details) for each request to see if the user is still enabled/authorized to do whatever he does. You can leverage stuff such as per-user revocation lists, or a minimum_issued_at that will validate any JWT iat field. This allows the "Logout from all devices" pattern, where that action will simply set a user's minimum_issued_at field to $NOW. All previous tokens will thus be revoked, without individuall revocation list checks.
- zsoltkacsandi 4mo ago> JWTs have a limited expiry timestamp, so you only ever need to maintain a revocation list for tokens not expired yet. Sessions have expiration timestamps too, and you can configure them however you like.
- littlecranky67 4mo agoYeah of course, but how does that relate to my point? With JWTs you don'T have a list of valid tokens as state, but only a list of invalid ones (revoked). But the list of revoked tokens in the last X hours (where X is your token lifetime) is always going to be smaller than the list of active sessions given a large enough user base. Hence my original point stands, that the lookup and storage costs are lower than on sessions. Whether or not sessions have session lifetimes does not change the fact at all.
- doctorpangloss 4mo agoisn't it that you must have a revocation list in many cases? if you cannot get from N to 1 or 1 to 0 states, if you're just going from N to N-1>1, you haven't materially decreased your statefulness
- littlecranky67 4mo agoBut the revokation list is always going to be orders of magnitude smaller than the list of active sessions.
- doctorpangloss 4mo agothat may be, but who cares how big or small it is really if you are facebook sized, with 1b+ active sessions versus an alternative with 10m+ revocations... the kind of applications that reach this scale, they have enormous amounts of state anyway.
- littlecranky67 4mo agoEverybody thinks Mag7 scale, but actually it is more relevant if you are a tiny webservice - but available world wide. If you need to match each and every http request from a user half way around the world against a central db, you can't beat the speed of light. If you can do authentication on each downstream server directly using crypto and JWT validation, you at least save that roundtrip to the session db. The revocation list is tiny (a few megabytes tops), append-only, can be public to the world, and thus easy to replicate to your downstream nodes. If you are a smaller gig, you won't have to bother with replicating your sessions and keeping them in sync globally.
- debazel 4mo agoA revocation list can often be lazily replicated and doesn't require the complexity of distributed synchronization. If you store sessions then you need to ensure the session has been replicated to every node before you can return it to the user. For revocation lists it is often acceptable that the token is still valid for a short while at some nodes while it is being replicated. A revocation list is also not considered highly sensitive data, which would be another complexity layer when working with distributed data.
- jpalomaki 4mo agoSession data lookup is one select to database that gives 0..1 rows and uses index. In most cases this is not something you need to worry about.
- littlecranky67 4mo agoI agree. The storage space, however, is a different story. Your session DB can grow huge, depending on your session lifetime and your users logout behaviour. Plus, it is a concern in a distributed system (i.e. a token can be validated on every node, vs. a session lookup must be globally in sync)
- 10000truths 4mo ago1. For the vast majority of CRUD apps, active sessions will be a very small fraction of the actual storage requirements. A SaaS with 100K MAU may have only 100 or so active users at any given time. 2. Sessions by definition are ephemeral. A database should not be necessary at all, an in-memory cache should suffice. 3. If you really need to distribute session data across multiple nodes, just propagate them asynchronously. Authentication and authorization are semantically idempotent operations. Having to possibly re-auth when making a cross-region request within milliseconds of logging in might be mildly annoying for the user, but consistency isn't a deal breaker here.
- littlecranky67 4mo ago> 3. If you really need to distribute session data across multiple nodes What you mean, "if" - you will need that once you are international. You can't afford to verify every http request against a centralized session store when you have users in Australia, US, Europe, Japan etc. You can't beat the speed of light. My point is, replicating revocation lists that are append-only, only a small megabytes, and can be publicly known, is always easier than syncing session databases for a complexity standpoint.
- matt-p 4mo agoCan even put it in redis too, if you have performance issues from looking for it in memory then you have probably have more users than google.
- vidarh 4mo agoThe moment you have to look up the user object, you've lost the primary advantage of JWT, and might as well ditch it.
- littlecranky67 4mo agoDepends on the system. If you use JWTs for authentication only, they still serve a purpose. Sessions also only serve as authentication, not authorization. Authorization is independent of the both systems, and it depends how you implement that. There are systems where the authorization is done in the JWT too (i.e. scopes/permissions in the token) - in that case you are right.
- joshmarlow 4mo agoIt definitely violates DRY but if you keep passing the JWT down the call chain, you can do redundant permission checking in your business layer. Now the reasonable response to the above is that this should be happening in a dedicated authn/z concern - and that is correct! But when paranoia is called for, it's not unreasonable to have redundant checks in logic where authz is critical.
- jollyllama 4mo ago> It definitely violates DRY DRY conventionally refers to repeated sections of code, not redundant communications.
- mekoka 4mo agoIt depends how you store and look things up. There are so many optimization opportunities and strategies to make the lookups fast that this is pretty much a non-issue in practice (e.g. deny list implemented as any combination of runtime or in-memory index, trie, or bloom filter). At the first invalid bit the lookup fails and the token is allowed to proceed to subsequent auth checks. Which should happen quickly for the vast majority. No need to head straight for the worst possible implementations, like whitelist disk lookups.
- owaislone 4mo agoThis. Totally defeats the purpose of having JWTs if you have to hit the DB or some service to validate the token every time.