10 ms·
You cannot invalidate JWT tokens This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add
by lynndylanhurley 10y ago
You cannot invalidate JWT tokens
This is simple not true. You ALWAYS will sign your tokens with a well known secret, you could eventually even add some salt from a database to it.
I think one of the benefits of some (most?) JWT implementations is that it doesn't hit the database on every request - the token is only validated against a global secret.
So you can't invalidate a single user's session without invalidating all users' sessions.
- Johnie 10y agoCan't you maintain session state in a Redis daemon and invalidate it there? Or are you talking about stateless JWT?
- DelaneyM 10y agoYou include the time created in the object before signing, and invalidate based on that as a timeout.
- dandelany 10y agoSure, but that's expiration, not invalidation, ie. we're talking about the ability to declare "this particular token is invalid now". Incidentally, this limitation isn't too surprising to me... Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able? Seems like any form of invalidation would require storing the "is valid" state somewhere else...
- DelaneyM 10y ago> Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able? I suspect this is provably impossible. There are all sorts of things you can do at the protocol/platform level if you have a shared secret, but with only the constraints of an open authentication scheme you lack the tools to do this.
- gcommer 10y agoIf you're willing to delve into the fun world of CRLs you can sorta do it. This isn't truly stateless of course, but for some design constraints it could be "practically" stateless since you're eliminating auth server round trips, which is probably why you were aiming for statelessness in the first place. CRLs of course introduce lots of replication complexity and timing bounds to consider, and you probably want to pair them with short lived tokens to keep the CRL size manageable. (and then delve into refresh tokens) As the OP points at, you most likely don't need any of this.
- merb 10y agoEventually JWT has very little Roundtrips. Our current Implementation is: - Really short lived JWT of 1 minute - If the JWT is invalid and the user didn't do a request in the last minute it does query the database for a session token (we use session tokens and jwt). if the Token is inside the database/redis/ehcache/whatever the user gets still a new JWT token. Actually we did that since we needed a "sane" way of revoking tokens fast but still keep the user logged in until the browser is closed. We don't have a mobile client (yet) but I guess we try to do something like that, too. just not with a session. This works really well and mostly our users won't hang around for more than a minute and when they do its not a problem to have a single backend call.
- seangrogg 10y ago> stateless (ie. no round trip to the database on every call) AFAIK, Stateless is about independent request/response and not needing a server to retain session information through the course of multiple requests. It has nothing to do with whether or not you're checking a database to cross-reference credentials - and I wouldn't keep anything more than an ID/name in a JWT... ever. https://en.wikipedia.org/wiki/Stateless_protocol https://en.wikipedia.org/wiki/Stateless_protocol
- sk5t 10y agoJWT is good for much more than an ID+name; it's sensible to allow your partially-trusted token issuers to vouch for a _limited_ set of user roles and the like. Just the same way you probably wouldn't allow the @acme.com security authority to vouch for @example.com principals in a multi-tenant system... in ye olde SAML lingo this is called "claim filtering / transform / passthrough." Practically speaking, we use a bit of metadata (jsonb documents in pgsql, mostly) for each JWT-issuing party, which describes how to validate principals, how to map incoming claims to "our" claims (e.g., "by what name does sts.acme.com call a 'role'? is sts.acme.com allowed to vouch for the 'admin' role?) in addition to the more central things like shared secrets, certificates, etc. This kind of partial trust is how claims auth is supposed to work, and avoids any unnecessary provisioning/syncing of user details.
- zeveb 10y ago> Is there any possible token-based authentication scheme that is both stateless (ie. no round trip to the database on every call) AND invalidate-able? SPKI (RFC 2692/2693) solved this in 1999, with its timed CRLs. Exactly one CRL is valid for any given period of time: when a token (= certificate) is received, it is invalid if it is referenced in the CRL, and valid otherwise.
- low_key 10y agoI keep a counter in the JWT to at least mostly get around this issue. When processing a request, the counter is checked for the user, which isn't a big deal since all of the requests already require looking up the user. A counter increment invalidates all of that user's existing tokens. If a user changes their password, their roles change, etc, then the counter gets incremented so all tokens issued up to that point won't be valid anymore.
- snikch 10y agoYep ^ This is what I often do too. Simple, but effective.
- ForHackernews 10y agoCan you explain this a little bit more? You keep a counter on the user object in the DB? What is the JWT buying you if you still have to hit the DB on every request?
- mstade 10y agoPresumably you can keep counters like these on the server edges, and just push new values out to servers whenever things change, as opposed to query a DB every time. This wouldn't invalidate individual tokens however, but all tokens that have that counter value. It'd also mean there's a window where tokens can still be used while servers are being updated with the new value(s). These are just some random and half-baked thoughts, I have no idea what OP does, but there are options to limit hitting backing DBs anyway.
- njknsdf 10y agoYou can store the user info in the JWT so you don't need to hit the database to get user info every time. I usually just store an id in each issued token and store/remove it from redis or memory as needed for invalidating it.
- ekryski 10y agoYou have to be careful that you are not leaking sensitive info though, as the JWT payload is meant to be visible on the client as well.
- seangrogg 10y agoI hit the database on requests - I keep their identity in the JWT but not their permissions. And if they're hitting a protected route (the only time their identity is necessary anyways) you best be sure I'm checking their canonical permissions.
- cortesoft 10y agoYou might be, but many people use signed cookie sessions in order to avoid having to check the DB.
- mcherm 10y agoYes you can. The system I built uses a revocation list (propagated to all servers in the cluster) to invalidate the session. Just as if you were storing state on the server, it still requires a means of propagating the user's state to every server. But we only need to propagate a single ID once per session (at logout) instead of propagating all the session data to all the servers on every request.
- brndn 10y agoOut of curiosity, how are you propagating the IDs to other systems in the cluster? I am building something which could benefit from pushing config data across a cluster.
- sk5t 10y agoIn most cases it shouldn't matter; revocation lists ought to be trimmed to the lifetime of the issued tokens--when they are used at all, revoking a JWT rather than just letting it expire is likely not extremely common--so you could stuff them anywhere at all that is convenient to your other technology selections.
- centrinoblue 10y agoit's my understanding something like Redis is good for cross cluster im-memory persistence/reference
- sb8244 10y agoDo you ever worry that, in the case of failure or some other event, your revocation list could be lost and allow old hacked sessions to be used? Is there a way around this? I like the idea of a revocation list, but this seems to be a pretty big concern.
- RhodesianHunter 10y ago"old hacked sessions to be used" JWTs generally contain an expiration timestamp.
- 10y ago