Hacker News new | ask | show | jobs
by Octoth0rpe 19 days ago
I have a pile of personal criticisms of jwt, but I don't think this article does a great job of arguing against JWTs. For example:

> You can't [invalidate a jwt]. That's the answer. The token is valid until it expires, full stop. The only way to invalidate it is to store the jti server-side in a revocation list and check that list on every single request.

...So the article says you can't invalidate a jwt, and not 2 sentences later, tells you how you can. Of course you can.

> [misc criticisms of refresh tokens]

Mostly agree with this part.

> RS256 verification is in the same order of magnitude as a Redis lookup. And you still have to parse JSON, validate exp, validate iss, validate aud, walk the JWKS cache for the right key, and allocate a few objects the GC has to clean up later. Multiply by your request rate.

I think this misses the mark a bit. Signing/validating a jwt can be done entirely on your application server, which should easily scale horizontally. Any kind of db lookup requires a roundtrip/bottleneck which introduces complexity. So, even if it's the same # of ms, there's still an inherent advantage for validating on your application server IMO.

> Almost no one does [front end verification]

Sure, agreed, but so what? It's a feature that no one uses. That doesn't invalidate other features of jwts.

> The advice goes: don't put the JWT in localStorage because XSS will steal it — put it in an httpOnly, Secure, SameSite cookie so JavaScript can't touch it. Read that sentence one more time. You have just described a session cookie. The browser attaches it automatically, the server reads it on every request, the client can't see what's inside.

Yes, I think from a client perspective, it's fine to think of it like just a session cookie. As many other commenters have pointed out though, it's like a session cookie _with super powers_ because once the request is validated by some kind of front end app server, you can pass that same token around to other backend server and trust the claims inside it and save each of those services from having to do their own lookup. This I Think is the real value of JWTs over plain ol' session cookies.

1 comments

Yes you can invalidate them, but comes at the cost that you have to write the machinery yourself, that is the point. If you miss something, that's security issues, and I say you can't just because people are not doing it, dont know about it, or think ITS SIGNED, I DONT HAVE TO DO ANYTHING ELSE. Which is false pretenses. Also term invalidation is kinda tricky. YOU CANNOT INVALIDATE IT in a sense token is invalid. It's backlist invalidation, you store it and say this is invalid if you encounter it. You can say it's the same thing for session, yes and no, session have to be stored, deleting them is invalidating them, jwt is build on promise that you dont need to do all this, and this is the pitfall.

> Sure, agreed, but so what? It's a feature that no one uses. That doesn't invalidate other features of jwts.

True is unused feature, but then stateless part falls apart, you don't save anything but introduce complexity and maintainance problems, someone will have to go over that code, understand it and not crew things up.

> I think this misses the mark a bit. Signing/validating a jwt can be done entirely on your application server, which should easily scale horizontally. Any kind of db lookup requires a roundtrip/bottleneck which introduces complexity. So, even if it's the same # of ms, there's still an inherent advantage for validating on your application server IMO.

My position here is, if I have to hit the database, well why then I need the signing part, or encryption part, whats the benefit of it. What I understand from JWT, you dont have to store anything. That was the promise of it, and yet for secure systems you have to store something, at least to be GDPR compliant. AFAIK you need to provide the feature LOGOUT FROM EVERYTHING by GDPR, dont quote me on that, it's what I've seen, not a lawyer, simple developer.

> Yes you can invalidate them

All I'm saying is that if you clearly can, then don't claim that you can't. Maybe claim it's inconvenient or impractical, but it's an absurd paragraph in the original article.

> True is unused feature, but then stateless part falls apart

Maybe a miscommunication, but that part of my comment was referring to validating the token on the client. I don't see how this makes them not stateless. The stateful/statelessness can be entirely confined to the server.

> My position here is, if I have to hit the database, well why then I need the signing part, or encryption part, whats the benefit of it.

It provides a useful token that can be validated once by some kind of front end application server, and then passed around from there to backend microservices which trust the validation from the front end app server. None of the backend microservices need to hit the database again. I tend to agree that the signing/encryption parts are not particularly useful, but that doesn't make jwt a scam (the premise of the article).

> yet for secure systems you have to store something, at least to be GDPR compliant. AFAIK you need to provide the feature LOGOUT FROM EVERYTHING by GDPR, dont quote me on that, it's what I've seen, not a lawyer, simple developer.

To do this minimally, you don't have to store anything under normal conditions. You only have to store the ids of revoked tokens, and only for the lifetime of the token that is invalidated.