9 ms·
"Just use the normal session mechanism that comes with your web framework and that you were using before someone told you that Google uses jwt. It has stood the
by jupp0r 2y ago
"Just use the normal session mechanism that comes with your web framework and that you were using before someone told you that Google uses jwt. It has stood the test of time and is probably fine."
You don't need to be Facebook or Google to have more than one service in your infrastructure that needs to authenticate a user's existing session without forcing the user to log in again. Sharing the session across multiple services is its own distributed systems problem with numerous security implications to be aware of and bearer tokens might be a good alternative.
If all you have is a single monolith web app that is the identity provider, makes all authentication decisions etc then yes, you don't need JWTs probably. There is a huge gap between that and being Google/Facebook.
Apart from that, Google and Facebook don't even use JWTs between the browser and backends after the initial login but actually do have some sort of distributed session concept last time I checked.
- _heimdall 2y agoThis is a perfect example of "it depends" being the right answer. Should a project use sessions or JWTs? One isn't right or wrong, it all depends on the context of the project.
- wokwokwok 2y agoI mean, to be fair, the article literally calls out a fairly reasonable checklist. Do you maintain a database of JWT session tokens for refresh and revoke? Do you have a real session that you load for every user every request anyway? If the answer is 'yes', then the answer to 'use JWT' isn't 'it depends'. It's no.
- _heimdall 2y agoThe author here seems to be arguing that you should effectively never use JWTs. That, in my opinion, is a mistake. JWTs have absolutely been over-hyped for the last 8-10 years, but they do have a use and you don't have to be at the scale of Google for it to be the right approach. Software isn't as simple as creating a checklist of a few basic categories and saying there is always a right or wrong answer. The answer should be "it depends" because there are many more factors at play when deciding something as fundamental as authentication and authorization.
- meindnoch 2y agoOk, then show us an example scenario where using JWTs makes sense, while the author's checklist says it doesn't.
- _heimdall 2y agoI may not have been clear there. I'm not saying the author's list is wrong, I'm saying its incomplete. For starters, the blog post leads with the premise that the answer is always "No". Even ignoring that as playful banter, the checklist is way to broad to be universally true. > You wanted to implement log-out, so now you’re keeping an allowlist of valid JWTs, or a denylist of revoked JWTs. To check this you hit the database on each request. > You need to be able to block users entirely, so you check a “user active” flag in the database. You hit the database on each request. > You need additional relationships between the user object and other objects in the database. You hit the database on each request. > Your service does anything at all with data in the database. You hit the database on each request. These all assume that I authorization data and that the user data lives in the same database. I may store my own user object with a unique ID that references an authenticated user, while the author flow is actually managed by an entirely different service (whether first party or third party). I also may have my user data stored in a separate database, say for legacy reasons or data security/integrity requirements. Not every database is crested equal, its totally possible that one database is a better fit for user data while a totally different database is needed for application data. Coming up with a list of broad scenarios and claiming that if you check any one there is never a reason to pick JWTs over sessions is misguided and overly simplistic. Context always matters. edit: formatting
- meindnoch 2y ago>These all assume that I authorization data and that the user data lives in the same database Please tell us how the following assumes that authorization data and user data lives in the same database: "You wanted to implement log-out, so now you’re keeping an allowlist of valid JWTs, or a denylist of revoked JWTs. To check this you hit the database on each request."
- Aurornis 2y ago> You don't need to be Facebook or Google to have more than one service in your infrastructure that needs to authenticate a user's existing session without forcing the user to log in again. Thank you. This middle ground between hyperscaler infrastructure and super simple web apps is where most of my career has been spent, yet the recent trend is to pretend like there are only two possible extremes: You’re either Facebook or you’re not doing anything complicated. It has an unfortunate second order effect of convincing people that as soon as they encounter something more complicated than a simple web app, they need to adopt everything the hyperscalers do to solve it. I wish we could spend more time discussing the middle ground rather than pretending it’s some sort of war between super simple or ultra complex.
- rescbr 2y agoSpecially since the middle is way larger than people think.
- kelnos 2y agoI still don't think people in the middle need JWTs. If we're talking about a web session, time-limited randomly-generated session tokens that are stored in a DB still work fine. If you really need it, put a caching layer (memcached or redis or valkey or whatever) in front of it. Yes, then you've created cache invalidation problems for yourself, but it's still less annoying than JWT. If we're talking about authenticating API requests, long-lived randomly-generated auth tokens stored in a database work fine, generally. (But allow your users to create more than one, and make rotation and revocation easy. Depending on your application, allowing your users to scope the tokens can also be a good thing to do.) Again, put a caching layer in front of your database once you get to the scale where you need it. You probably won't need it for a while if you're sending your reads to read-only replicas. (Source: worked at Twilio for 10 years; we definitely eventually ran into scaling problems around our user/auth DB, and our initial one-auth-token-is-all-you-need setup was terrible for users, but these problems were fixed over time. Twilio does use JWTs for some things, but IMO that was unnecessary, and they created more headaches than they solved.) I'm not saying no one ever needs JWTs, but I think they're needed in far fewer circumstances than most people think, even people who agree that JWTs should be looked upon with some skepticism. If you need to be able to log people out or invalidate sessions or disable accounts, then JWTs are going to create problems that are annoying to solve. (One possibly-interesting solution for JWT-using systems that I haven't tried anywhere is to do the reverse: don't cache your user/auth database, but have a distributed cache of JWTs that have been revoked. The nice thing about JWTs is that they expire, so you can sweep your cache and drop tokens that have expired every night or whenever. Not sure how well this would work in practice, but maybe it's effective. One big problem is that now your caching layer needs to be fail-closed, whereas in a system where you're caching your user/auth DB, a caching layer failure can fall back to the user/auth DB... though that may melt it, of course. I also feel like it's easier to write logic bugs around "if this record is not found, allow" rather than "if this record is not found, deny".)
- closeparen 2y agoWhy would there be any relationship between user sessions and microservices? Are you exposing them directly to the internet?
- jupp0r 2y agoHave you ever wondered why you don't have to login when you go from photos.google.com to docs.google.com?
- Illniyar 2y agoIt's pretty rare to have more then 1 client facing API even for large apps. Whether it's a monolith, an API gateway, Apollo federation or whatever. What you do to authenticate between the BFF (for lack of a better name) and other services is a different matter.
- unscaled 2y ago> Sharing the session across multiple services is its own distributed systems problem with numerous security implications to be aware of and bearer tokens might be a good alternative. JWT makes it possible to distribute the same access token across multiple systems, but so do stateful tokens. The security implications when you're using JWT for this solution are much higher than with database tokens. Let's look at this for a moment: JWT Security Issues: - Inherent design issues (alg=none, algorithm confusion, weak ciphers like RSA) - Cannot be revoked. - Key rotation and distribution is necessary to keep token safe over a long period of time - Claim parsing needs to be standardized and enforced correctly in all services (otherwise impersonation is possible) Database Tokens Security Issues: - Timing Attacks against B-Tree indexes [1] - Giving direct access to the database to all microservices is risky The security issues with databases are ridiculously easy to solve: To prevent timing attacks, you can just use a hash table index, split the token into a search-key part and a constant-time-compare part or add an HMAC to your token. To prevent direct access to the database by all your microservices, you just wrap it with an API the verifies tokens. The JWT security issues are much harder to solve. To prevent misconfiguration or misuse and standardize the way claims are used across your organization, you probably need to write your own library or deploy an API gateway. To counter the lack of revocation support, you either need to use very short lived access tokens (so your refresh token DB will still get a lot of hits and you would still need to deal with all the scaling issues) or set up a distributed revocation service (not easy at all). Setting up seamless key rotation also requires additional infrastructure that is not part of the hundreds of JWT libraries out there. It's really easy to get a JWT solution that just works and scales easily, but if you really care about security — especially if you care about security! — JWTs are not necessarily easier than stateful tokens. They're probably harder. > Apart from that, Google and Facebook don't even use JWTs between the browser and backends after the initial login but actually do have some sort of distributed session concept last time I checked. Last time I checked (which was today for Google), neither Google, nor Facebook is using JWT for their access or refresh tokens. The only place I saw JWT with the ID Token in their Open ID Connect Flow, and they can't really avoid that even if their wanted, since this is mandated by the spec. Facebook and Google don't need JWT. Scaling and distributing a read-only token database to handle a large amount of traffic is easier — not harder! — for these companies. Stateless tokens can be useful for them in certain scenarios, but even then, if you're at Google or Facebook's scale, why would you opt for JWT over an in-house format that is smaller, faster and suffers from less vulnerabilities? [1] https://www.usenix.org/legacy/event/woot07/tech/full_papers/futoransky/futoransky_html/index.html https://www.usenix.org/legacy/event/woot07/tech/full_papers/...
- pojzon 2y agoJust use elasticcache for sessions duh. Its a very very old pattern.
- likis 2y agoAgree, and he even mentions in the article "If you process less than 10k requests per second, you’re not Google nor are you Facebook." There is a huuuuuge gap between services handling 10k req/s and Google/Facebook. I think one big upside with JWT that he doesn't mention is that if you have some services geographically distributed, then having decentralized auth with JWTs is quite nice without having to geographically distribute you auth backend system. So, yes, if you have a monolith or services colocated, or have some kind of monolothic API layer, then no, perhaps JWT does not make sense. But for a lot of distributed services, having JWTs makes perfect sense. And you don't have to introduce JWT revocation for logout, if you have short token expirations, you can accept the risk of token leakage. If the token is valid for like 30 seconds or 1 minute, you would probably never be able to notice that a token has been leaked anyway.
- Hendrikto 2y agoBearer tokens are simple until you have to invalidate them. Then you get all the complexity of both solutions.
- supermatt 2y agoAs per the JWT spec: “ Finally, note that it is an application decision which algorithms may be used in a given context. Even if a JWT can be successfully validated, unless the algorithms used in the JWT are acceptable to the application, it SHOULD reject the JWT.” There is no reason you can’t keep a list of valid “session” identifiers and check the JWT is valid against that as part of verification. Then the only state you need to store server-side is the identifier. You get the exact same benefits of server-based session stores without needing to store the entire session on the server - just the identifier.