8 ms·
The JWT has a built-in field called exp, which is the time the token is expired. This is built in. However if you need to 'expire' a JWT token early, there isn
by redbeard0x0a 8y ago
The JWT has a built-in field called exp, which is the time the token is expired. This is built in.
However if you need to 'expire' a JWT token early, there isn't a good way to do it. If your token has a JTI, then you could add a blacklist for that JTI (say in redis, with a TTL until the token's exp time). But that is left to the implementor.
- sjroot 8y agoThe page mentions the ‘exp’ field, but doesn’t use it in its example. I was suggesting the author point out the fact that, if someone gets a hold of a JWT without an expiration, then your system is in quite a bit of trouble.
- shkkmo 8y agoIt is up to your implementation if you consider JWTs without an exp field to be valid. Our implementation requires a number of fields that are optional in the spec.
- crescentfresh 8y agoSo that's what JTIs are for!! I disabled [generating] them in our app, I couldn't figure out what purpose a unique-identifier-per-jwt would have, when you could just use the jwt itself to uniquely identify itself.
- incadenza 8y agoMy issue here is that expiring JWTs involve adding state! The whole point of JWTs is stateless authentication, so I’ve never understood the advantage over sessions unless revoking tokens is never an option.
- evan_ 8y agoOne way to look at it is, presumably you will have far fewer revocations than active sessions, so why optimize for that case? Instead of an "active sessions" table you could just maintain a list of revoked sessions and check each incoming request against that list. You can make revocations expire shortly after the JWT was set to expire.
- hinkley 8y agoWhen are you expiring tokens ahead of their natural expiration date? When someone logs out? Isn’t that state? If you add state to something stateless you are generally on your own. [edit: also I disagree with the notion that something with an expiration date is stateless. It has two states. It’s just that the look like idenpotence]
- incadenza 8y agoPerhaps revoking is the better term here. At least that's the use case I had in mind. If you want the ability to revoke a token, you have to have some list of black listed tokens somewhere.
- iamwil 8y agoWhen someone's account is compromised, is another situation.
- geezerjay 8y ago> When someone's account is compromised, is another situation. Why is that scenario relevant if tokens are supposed to be used once per request and short-lived? Once a token is used, it's supposed to be expired and no longer in use. Both the expiry timestamp and the nonce fields already handle those use cases.
- iamwil 8y agoSuppose to be once per request and short-lived. But that's not specified in the thread above. Previous person mentioned logout, so I assumed we were talking about session tokens--which I understand its a misuse of JWTs--and is why he/she's mentioning it. But if we're talking about just one time auth tokens, then yeah, you don't need expiry ahead of the expiry time, and it's plain it's a non-issue.
- geezerjay 8y ago> My issue here is that expiring JWTs involve adding state! I don't agree. The expiration timestamp is not a state, nor is a nonce/token id. Moreover the specs enable servers to arbitrarily reject tokens, which means servers can arbitrarily request token refreshes. This means that any argument regarding how a nonce is a state is entirely irrelevant and without any practical interest.
- incadenza 8y agoWhy would you arbitrarily reject a token refresh? The question here is which token to reject. That's where the state comes in. If a token is compromised, you have to know which one. Hence, stateful.
- geezerjay 8y ago> Why would you arbitrarily reject a token refresh? You've misread what I've said. The server can trigger token refreshes by rejecting the request. According to the JWT workflow, that triggers the client to request a new token and retry the request. > The question here is which token to reject. That isn't much of a question, because servers are free to reject any token arbitrarily. They can, however, ignore specific tokens that cease to be valid, such as expired tokens or tokens which have already been used. None of those scenarios involves any change to the token's state.
- incadenza 8y agoI'm failing to see how this is complicated. Imagine the following: 1) A token gets compromised. 2) You know which token. You need to revoke access. 3) You introduce state by storing said token on disk / in memory somewhere. Key takeaways: 1) The authentication system (not the token) is now stateful. 2) You now have to check this data store to properly allow authentication. 3) A core benefit of JWT (stateless auth) is gone.
- geezerjay 8y ago> 1) A token gets compromised. Tokens are single-use and short-lived. Once a token is used it's revoked. > 2) You know which token. You need to revoke access. > 3) You introduce state by storing said token on disk / in memory somewhere. You don't. You simply reject the token and let the client refresh its token. That's it. There is no state. Compliant clients already expect tokens to be rejected for no apparent reason. They are access tokens. Why exactly are you assuming that an access token is not single-use or even short-lived, particularly in bearer token protocols specifically designed so that tokens are ephemeral and single-use? > 1) The authentication system (not the token) is now stateful. Even if you shoehorn your definition of statefulness, that's entirely irrelevant. The whole point of an authentication system is, following your line of reasoning, to implement a stateful system. Thus, not only is that line of reasoning absurd, it also completely misses the point of implementing an authentication system, not to mention it ignores a whole class of attacks. And for what, exactly?
- andrewstuart2 8y agoInvalidation of any sort, including token revocation, is fundamentally a stateful operation. Either you are deleting session state or statefully blacklisting something that's a packet of self-contained state (e.g. JWT by id). Heck, even expiration just reduces the revocation into the universally shared state that is time. My point is, you always have state. If you care about that state being anything but _the current time_ (e.g. just letting tokens expire and not worrying about revocation), you need shared storage.
- tptacek 8y agoIf you always have state, what's the point of making tradeoffs to get closer to "statelessness"? I see clearly why some small subset of applications benefits from carefully minimizing shared state among components. It is not at all clear to me why pseudo-statelessness is a good default.
- andrewstuart2 8y agoI'm not sure you're actually asking for my opinion, or just making a point, but IMO, the "statelessness" most people describe with respect to web services simply means that a single request already has as much as possible of the information required (outside of current time, securely fetching/validating public keys, etc) to process the request. The point is that it's easier for distributed systems as a whole when clients hold onto their client-specific state, rather than a minimal token that the server, likely being load balanced for availability, must exchange for that state with yet another service in yet another stateful/authenticated request/response manner.
- tptacek 8y agoMy subtext is that gains from moving state from the server to the client are often swamped by the first serverside database round trip that has to be done to service requests. So, you see ActiveRecord Rails applications using JWT, and it's like: the benefits of "statelessness" are not rationally why this got deployed.