JWTs are good for API tokens, not end users. If you use JWTs for your cookies/session state, then you'll still need to maintain a table of valid JWTs and expire them when the user logs out, and thus you will not be able to use JWTs as they were intended to be used, which is as stateless tokens.<p>Most security auditors/certifications/compliance requirements do not consider even a 5 minute lag acceptable for user driven logout. The definition of logout is that when the user presses the logout button, all the session data is invalidated server-side during roughly the time it takes for a request/response roundtrip.<p>Thus there is no benefit to using a non-opaque high entropy string for user sessions, even though there is a good benefit to using JWTs as API tokens for back-end services (esp. microservices) that do not have browser logout requirements.
JWT are useful where logouts are rare (games/apps), high API volume or some latency between logout and actual logout is acceptable.<p>Think of apps like Uber. Millions of DAU, but rarely people explicitly log out. If your logged-out user list is 5-6 order smaller than active users, it is easy to replicate/cache that. Very high API volume to many different services. Apart from few, majority of APIs won't have major security implication, if called by a rogue actor calls them.<p>So yeah, banks shouldn't use them, Farmville/Uber using them is perfectly fine.
"Statistically, most of us are building applications that won’t make a Raspberry Pi break a sweat."<p>I keep repeating that, but the dev community is really susceptible to the "temporary embarrassed billionaire" syndrome.
The amount of JWT tutorials available right now is absolutely overwhelming. I found myself worried actually that session tokens were <i>insecure</i> just because I could not find recent documentation/tutorials on them.<p>I asked for suggestions on r/node for alternatives to JWT and the first comment was "Just use JWT".
I feel like the author doesn't mention one thing that I always thought was one the best advantages of using tokens stored in browser localstorage instead of cookies which is that the risks of CSRF attacks are lower/gone?<p>Cookies _always_ get sent with every request, so an attacker site can make a request to your API and if the user is logged in there, they can do as they please with that user's session... so CSRF tokens then need to be sent with any request which adds a bunch of other complexity.<p>If authentication is handled with a token stored in localstorage rather than a cookie, no other site has access to the token and thus through more authentication hoops one need not jump.<p>Am I just horribly confused and wrong about all this?
As an side, the author mentions that people who use JWT instead of sessions can be likened to those who learn React/SPAs instead of conventional approaches:<p>> This is similar to many newer developers learning how to build SPAs with React before server-rendered HTML. Experienced devs would likely feel that server-rendered HTML should probably be your default choice, and building an SPA when needed, but this is not what new developers are typically taught.<p>I do agree with that point. It's important to learn the fundamentals before jumping into large frameworks and potentially over-engineering things in the future.
To be perfectly honest I thought JWTs made a lot of sense until I actually started trying to deploy them in a SAAS side project I was working on. It turned into a comedy of errors and I just decided to go back to cookie based authentication which worked out much better for me. I like the idea, but in practice JWTs were more hassle than they were worth.
I think you are overlooking the main benefit of JWT - is to allow authentication by a trusted third party, thus enabling single sign on, eliminating the need for password storage and management, login forms, etcetera.
Minor nitpick—<p>“Often, sessions and cookies are described as 2 different things, but they’re really not. A session needs a cookie to work.”<p>This is false. Inital JAVA Servlet specifications supported session id in the URL.
> If they’re not safe, what chance does the general (developer) public have?<p>Something I've been wondering is, do we really have any evidence that the average Auth0 developer is more of a security expert than any other dev?<p>I'm sure they have security experts on staff designing systems but it doesn't seem likely that everyone doing the building is an expert. They are as likely as any to code in mistakes
1. I think it's important to compare the security issues that JWT has had to the alternative. There, 'vanilla' cookie auth (which I assume to be session IDs) is <i>by far</i> the biggest offender.<p>2. It's not true that JWT is not stateless and therefore irrevocable. RFC7519 defines 'jti' for exactly this reason:<p>> The "jti" (JWT ID) claim provides a unique identifier for the JWT.<p>> The identifier value MUST be assigned in a manner that ensures that<p>> there is a negligible probability that the same value will be<p>> accidentally assigned to a different data object; if the application<p>> uses multiple issuers, collisions MUST be prevented among values<p>> produced by different issuers as well. The "jti" claim can be used<p>> to prevent the JWT from being replayed. The "jti" value is a case-<p>> sensitive string. Use of this claim is OPTIONAL.<p>I think the rise of JWT stems from the fact that unlike traditional auth tokens (see the bundle of entropy legacy OAuth tokens were) they are human readable. When I set up an OAuth API that a user hits, I can exchange a short lived OIDC id token for a long lived capability based bearer for greater security -- and when developers use my API it's easy for them to tell why their capability token doesn't work without having to fire off a bunch of requests and guess.<p>Edit: it occurs to me that the question of the JWT being 'stateless' might be about how session based storage often changes, but a JWT is largely immutable. Just for what it's worth, a session should not be revoked simply by removing it from the user cookie, or an attacker can persist simply by refusing to allow the cookie to be removed.
> However, these new technologies create a lot more buzz than their simpler counterparts, and if enough people keep talking about the hot thing, eventually this can translate to actual adoption, despite it being a sub-optimal choice for the majority of simple use-cases.<p>I hate this about the Node/Javascript community.<p>Whenever I need to learn how to do something in Node js, 4 out of 5 blog posts or tutorials will be about some overly complicated technology or new, shiny thing instead of the classical way.<p>Man, I just want to do the same shit we were doing in PHP 10 years ago, but this time I want to see how to do it in Node/Express. Is that too much to ask?
I’ve spent the last couple weeks ripping out JWTs from a site and just using cookies for auth, being that the site and the REST APIs are all on the same domain & servers anyway, and doing all the OIDC/OAuth and refresh token handling on the (ASP.Net Core) backend.<p>I have to say, considering how “simple” some of this stuff is conceptually, it’s been surprisingly complex with a lot of nuance in areas. I can see why they say “never role your own security”. It is dangerously complex even to implement common patterns well. I hope future standards and frameworks can make this space simpler and safer.
If your end user is using a browser, the session/cookie is the right mechanism to use. Even though it seems more convenient to use JWT instead of a regular cookie, since JWT is not recognized by browsers, there are security gotchas when using JWT as a replacement for session.<p>JWT makes sense to authenticate microservices within a trusted network where a gateway server logges the user into the network using a session. Microservices within the network communicate via JWT where the user does not have direct access to them. There should be a separate server that does the lookup for specific services.
JWTs are great! You get to use your customer’s machine to store a lot of information about them and the session in a form they can actually read in most cases, and your don’t have to do a bunch of lookups each time they connect.<p>Sure, you have to keep a revocation list, but you do anyway, for the same reasons.<p>If you use short lived sessions with refresh tokens you get the Goldilocks scenario where a valid user stays logged in even when they are away for a long time, and you give them control over logging out instantly on all devices and access to the data you’re using about them.
There's a neat little chart which explains why you'd probably be better off not using JWT:<p><a href="http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/" rel="nofollow">http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo...</a>
> Experienced devs would likely feel that server-rendered HTML should probably be your default choice, and building an SPA when needed, [...]<p>Is there any good article why SSR is any better than SPA? I really do not see any advantages of SSR, especially for pages where you need to be logged in and data to be displayed is acquired via an API.
An insanity has just occured to me: you could update (i.e. regenerate) the user's ID to invalidate tokens, fixing the logout issue and keeping the architecture stateless :)
Sorry for offtopic. Can somebody recommend up-to-date book discussing authentication and access control methods in web applications/API, there strengths and drawbacks?
Does JWT always imply statelessness?<p>We use JWT to send bunch of public claims around, one of which is session_id which refers to session in backend cache.
Are we doing it wrong?
I'd say this heavily depends on your stack.<p>In my experience Django Rest Framework with JWT + Vue or React on the frontend + some JS package that stores and refreshes tokens is solid as a rock and easy to implement/maintain. Your end users will never need to know what JWT means and you won't need to do any kind of token management. As far as I know, Instagram's stack is a variant of this.
The author says one of the selling points of JWT is scale, and points out many will not need to concern themselves with scale and to stick with simple solutions. But I am curious to know if any on HN is using session cookies at scale and how they solve the scalability issues of session cookies alluded to in the article?
> it has a ton of features and a very large scope, which gives it a large surface area for potential mistakes, by either library authors or users of those libraries<p>I mean that could apply to so many things — PKI, Windows permissions, and countless other things. It definitely strikes a chord with me.
The problem is lack of thorough best practices on how to using JWT on a JAMStack WITHOUT secure, same-site cookies.<p>There're many edge cases to cover but as i see, there's none of best practice guide on how to do your own !
How about salt the token with an additional user-specific random string. During log-out, you replace the random string so it no longer matches. Then, we can have partial check (only signature validation and expiry time) and full check (compare with the salt hitting some store). Full checks can be done only for API calls which deal with sensitive stuff or/and for writes (writes are less common than reads)<p>For example, fetching an article on something like New York Times would only require a partial check, but the profile page would have full checks.<p>Does it make sense?
this author is a fucking genius. i always say that the smartest people can take complex subjects and make them seem simple. this dude turns sessions and jwt into childsplay. this guy is a fucking genius.
Why is "JWT" not defined or explained until I scroll a few pages down and find one that's hyperlinked? I thought it was talking about the James Webb Telescope this whole time.
The article and associated links are weak on details - most of them are some form of setting the alg incorrectly.<p>> First, it’s a complicated standard<p>Actually it's remarkably simple and very well thought out; I frequently generate them in plain bash for testing. It is the simplicity that makes me trust JWT (where appropriate).<p>> If they’re (Auth0) not safe, what chance does the general (developer) public have?<p>Auth0 forgot to check latter case in alg = 'none', a very basic coding error. These errors can happen anywhere, and anyway use a whitelist for algorithms. The other links are quite similar, such as using a weak alg.<p>> A last issue with JWT is that they are relatively big, and when used in cookies it adds a lot of per-request overhead.<p>Most apps simply put userid and roles in the JWT, and that's negligible overhead. Of course there are people who do it wrong, but there are also people who store 10MB of data in a session.<p>My view is that JWT has a place in the future, and it works well even with decentralized systems. The ecosystem around JWT is rich, and over the years has evolved to solve many common usecases which come up in production. An example would be the JWK/JWKS spec, which greatly simplify how verification keys can be fetched.