Benefits
- Easier to (horizontally) scale: that's true. My previous company shut down a few servers thanks to JWT
- If it has a vulnerability, just update to patch it ... instead of fixing your customized algorithm. It's way better, but you need to use the most popular / battle-tested / maintained library for your language and keep track of its CVEs as any another dependency.
Drawbacks
- Not revocable, but you can 1) make it short lived, 2) create a blacklist check in a key/store database or 3) tie another verification to it with the cost of a database call (https://dadario.com.br/revoking-json-web-tokens/). Regarding the article (part 2), when it says what would happen if your server is down .. seriously, it's way easier to anything but a key/store value of a few items to get down first than any other server
- Developers think that the data is encrypted, when it's only base64'd
- Libraries have to make up for the flawed specification that allows the JWT to carry both the algorithm used and the signature
- Libraries are not as battle-tested as cookies
- Libraries may support flawed algorithms (e.g., RSA with PKCS #1v1.5 padding - for JWE), thus you have to know what you're picking
Some points that I agree or partly agree with the author of such article:
- Easier to use: that's nonsense. I'd say that it's the same thing as implementing a cookie mechanism
- Works better on mobile: that's nonsense
- Works for users that block cookies: you can very well put your session token in the LocalStorage and achieve the same effect
- They take up more space: true
- Built-in expiration functionality: that's nonsense. Cookies have it as well.
- By storing it on LocalStorage you avoid CSRF, but you can do that with session tokens already. Regarding the links above that 'by using JavaScript you open up your application to a lot more risk' .. well, to build a page without JavaScript in 2017 is madness. Let's get back to reply with full HTML content again? Lol. Backing to the point, it's not really a benefit of JWT, but commonly related to tokens that you store on LocalStorage, even though they're subject to XSS, as opposed to cookies w/ HttpOnly flag -- and then we go again to discuss how this flag only passes a 'false sense of security' because if you have a XSS, you already have lots of trouble.
Topics that are complicated:
- Saying 'more secure' or 'less secure' depends on how it is implemented. You could have secure JWT implementations and flawed stateful session implementations.
- Data goes stale: depends on what data you put on it! Just putting the user's UUID is not something that is likely to change, except when the user is removed;
The right comparison is JWT vs. session tokens stored in DB or KVS. Or in case you already decided against storing sessions in DB, you should compare JWT against rolling your own crypto.
With this approach, cookies should be thought more as a mechanism for storing and presenting session data, not as security mechanism. You can't rely on cookie expiry date for instance - if someone steals that cookie, they can completely disregard expiry, HttpOnly, Secure, Domain or whatever other property you stick to the cookie.
Cookie expiration is basically worthless. Whether you're storing your sessions in a database or cryptographically signing them you should always add your own expiration mechanism. I've seen too many systems that blindly relied on cookie expiration for security, only to realize the implications later.
You're right when it comes to terms. Allow me to clarify what I meant by Cookies and JWT in the explanation above:
I was referring to Cookies as the default storage for stateful session mechanism used by web frameworks that makes use of a random session ID with high entropy. It's the no-brainer approach to implement stateful sessions and (usually) doesn't require changes on the client-side but require you to store all sessions in a file/redis/db. And expiration that you pointed now makes sense, because I'm talking about the expiration of the session on the server-side, although Cookie has this mechanism which does little to prevent session hijacking.
JWT, on ther other hand, usually is stored on LocalStorage and requires some development changes on the JavaScript framework because it needs to read from LocalStorage, capture the JWT and send it in every request. With a web framework's default approach (that I used the term Cookies), it's seamless.
Doesn't it depend on the specific implementation? For example I have been using github.com/dgrijalva/jwt-go package to build a token, add claims and sign it along with github.com/auth0/go-jwt-middleware to validate the requests. The JWT in that case is signed and encoded as a string using the secret.
>> It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. <<
AFAIK LocalStorage is disabled when cookies are disabled.