So many articles, courses and project “starters” on GitHub suggest using JSON Web Token (JWT) on your client facing API as a session token.
There’...
For further actions, you may consider blocking this person and/or reporting abuse
As our industry shifts our paradigm from monoliths to microservices, knowing JWT is quickly becoming a requirement. Sometimes it is good to use the new shiny toy as an excuse to learn it. Even if your app serves less than 4,000 requests per minute and JWT would be overkill for your application, learning JWT and having practical knowledge of it is also of value.
This is one area that is definitely overlooked and also complex. The most common solution for this is on the auth server itself, which will keep a list of users that are authenticated, expiring them when they log out. On each request the token will need to be checked against the auth server to see if the token is still valid. This adds significant overhead.
More commonly, most companies will decrease the expiry of the JWT, so it must be refreshed more often. This is due to the difficulty and overhead of managing a true logout experience.
JWT is secure, but it is at the same time less secure than session based authentication. For example, the JWT is more vulnerable to hijacking and has to be designed to prevent hijacking. An unexpiring JWT can become a security risk.
You are also trusting the token signature cannot be compromised. This can happen if you are using weak encryption, encryption that becomes vulnerable in the future, or having the the private keys compromised. This vulnerability doesn't exist with sessions.
So while JWT is secure, it introduces new attack vectors that need to be considered.
There are valid reason to use JWTs:
JWTs do not come without their own complixity:
Unless scaling your system has driven you to microservices as a point of last resort, they're usually the wrong answer. Over the next couple of years, people are going to figure that out the hard way.
I don't know why JWT would be a requirement for microservices, though. A user connects to an HTTP server, the JWT token is checked there, and the HTTP server connects to other microservices with the user information as part of its request. There's no reason to pass the JWT around.
I am going to disagree with this statement. It sounds like you are suggesting JWT is a BAD option and should only be used as a last resort. JWT is just an option. And what you choose is will depend on your specific application and needs. So there are times when JWT is the BEST option.
To make a blanket statement saying JWT is always a BAD option is just not valid.
No technology is never a requirement, but an option... A tool available to us to choose and use.
Blanket statements like show extreme bias and because of this bias become easily dismissed. To prove "no reason" is impossible. There's always a reason.
I wasn't saying that JWT was usually the wrong answer. I was saying that microservices are usually the wrong answer.
Can you provide a scenario where passing a JWT around among microservices is a good idea?
I'm starting to feel like I am being Sealioned here.
Not my intention. I genuinely would like to know of such a scenario, since I can't think of one.
I can't disagree with this sentiment more strongly. While I've seen many a distributed system setup incorrectly, I've never seen one worse than a monolithic architecture.
That's a hard shell, soft center security approach which is very vulnerable to attack.
Static site with API backend is not a use case for using JWT.
I use “static” frontends regularly with GraphQL backends and still use sessions with secure httpOnly cookies so they can’t be accessed by the browser.
IMO JWTs are okay for what I refer to as “loose” authentication (when you quickly want to hide some nonsensitive data behind a login using a service such as Auth0 but your not necessarily exposing sensitive data).
Always, when exposing potentially sensitive data, use sessions with secure httpOnly cookies.
it is also not NOT a use case.
I like JWT when you have multiple distributed systems that need to share a single authentication that a single system doesn't have the authority to maintain itself.
Authentication as a Service.
Good article, but I can't agree on the ideas you brought up. An http cookie is a technology that originated from the browser world. JWT is agnostic and is not bounded to any platform or technology. We use JWT to store userId only. Sure both cookies and JWTs can be used in similar ways, but it's all about the intention of the code/solution you are building. And when using JWT the intention is a universal token that can be used anywhere and stored any where and not a cookie.
And the security of localStorage is not the joke that cookies are. blog.meteor.com/why-meteor-doesnt-... But when your entire argument is based on 'its probably good enough', then the presentation of new evidence is unlikely to change a thing. So have fun with your cookies!
Actually, it's assumed that generation of JWT and exchange of it has to be conducted through SSL for security reasons.
So I don't really think JWT is redundant since it's use case is more suited for API gateway backend to authenticate API services of a given user.
You don't keep secrets in the JWT. Everything in a JWT should be considered public.
First of all JWT is not encryption. It is authentication and authorization.
I can't tell you why you need JWT because I do not know anything about your application. But I can tell you why I am using it.
The environment I am working in consists of multiple disconnected systems, each maintained by different departments. JWT allows us to to create an authentication service that is disconnected and also works across multiple systems.
This is a complete misunderstanding of JWT and realky has nothing to do with JWT.
Encryption (checking the token contents against the signature) works to ensure that everything in your JWT token is valid and hasn't been altered. So it's public, but you can trust it.
That’s not encryption, that’s just signing. The data in a JWT is base64-url encoded, but otherwise easily readable.
There is a standard for JWT encryption, but that’s a whole extra level of pain.
I've been fighting several days to convince the other developers of the startup that I work for that JWT is not the ideal solution for authentication, I'm happy that there are other people who are talking about this :D
I think they all suggest JWT because it's easy to setup and lots of tutorials about single page applications just re-iterate that since it can be controlled by JS.
Exactly. That to me is the weakest argument
There was a really interesting discussion one year ago about using JWT and the local storage here if you're interested:
Please Stop Using Local Storage
Randall Degges ・ Jan 30 '18 ・ 11 min read
This is my favorite resource so far on the argument JWT and sessions: Stop using JWT for sessions, part 2: Why your solution doesn't work
ps. dev.to doesn't use JWT for the session, just to store additional user info.
JWT allows a way to not have to check a central DB for every request to say an API. Albeit not w/o drawbacks as covered by this piece. So instead of -- 1) receive request, 2) look up user's session for info and to determine if it's valid, 3) serve user request -- with JWT you can eliminate step 2.
As the author describes for most small and medium sites, validating a request against a central session store is really not that onerous. It's only when you get into Netflix territory - then you have to worry about how to distribute all that state where it's always available and accurate in real time for any service that needs to authenticate the user.
I think a big part of JWT should be some type of API Gateway.
In an example case (microservices) we take an API key from the client and the API Gateway creates a signed JWT with relevant user info. This is where blocked/logout checks will be handled.
With this, the JWT gets passed to the corresponding API service and it won't have to check again with the API Gateway on the given JWT. The JWT can also be passed to subsequent services if needed on behalf of the parent service.
1 call to user info is needed in this scenario. And the N microservices within the API request scope doesn't not need to check user auth.
API Gateway? Sounds more like an auth server.
"The JWT can also be passed to subsequent services if needed on behalf of the parent service.", that's a risk not a feature.
i havent dealt with this situation before
but what the auth api gateway .. will hand to the services ? the user id right ? will that be on the header ?
thank you
The Jwt is for your back end, not your UI. The web client doesn't need to validate it, only pass it along with it's requests.
Nah pretty sure SSL doesn't work this way.
Since that technology just provides you a encrypted tunnel.
It does not identify you as who you are as a user besides basic information of the computer you are using.
Great observation.
I would refute with two points:
1) Your application doesn't need it now but if it's a real application then you should always be getting ready for the future. JWT support is extremely easy to add now-a-days as any production-ready web framework will support out of the box or with a plugin.
2) JWT is a common standard for handling several different concerns. Having it implemented out of the box means it will already be there when you actually do need it.
I personally design everything with a scaling-first mentality. It's easy to neglect scaling until your awesome app crashes at the awesomest time ever and you lose all of your awesome users and you awesome clients don't feel awesome about paying you an awesome amount of money.
I don't see how cookies are going to stop your scaling? Get user info and store it in a cache with TTL.
You don't need JWT, so don't take it that way; but I think you've perhaps had some difficulties and you're perhaps missing a thing or two:
All of this is not to say you can't (or shouldn't) use session-based auth -- go ahead! JWTs just make it easier to:
Doing JWTs properly is hard. I've done it a few times -- and wrong a few of those times! But where I'm standing, the friction to get them working with something like IdentityServer is so low and the benefits for "heavier" client-side web applications outweigh the small setup cost.
But how do you check wether an user is authenticated or not in a single page application? What if I'm running an app and web app on the same API?
It's quite straightforward:
what do you mean?
Android App & Website sharing the same API & Authentication service, how are you supposed to store a cookie on an app?
You're not bound to have the same authorization mechanism for both services if it doesn't suit your Android app, but you can:
A cookie is just a header (not much different from the
Authorization
header OAuth2 uses), your app has a HTTP client, they usually handle cookies easily.I'm quite sure there's a way to store a cookie in Android, by Googling I found these:
I do not know how up to date such info is because I have zero experience developing on Android but I do know that whenever you have a decent HTTP client, you have support for cookies (they are not a new technology ;-))
If you're sending http requests with headers back and forth than you must have cookies because cookies are essentially just a header. Right?
These also add a stateful component to the API. If you want people to still be logged in after node restart or if you ever need to scale beyond one node, then you have to make sure your sessions/CSRF tokens are stored in a shared database (e.g. Redis). This creates extra failure modes to handle (session store down or overloaded) vs verifying the JWT signature. Session cookies are a great solution for many cases, but it has trade-offs too.
Yeah you are assuming that it identifies the user who are using it but the SSL only identify the computer itself is being used but the problem is that you can have multiple ppl using the same computer. So it is not that specific to the point of that it identify the correct information the user is using at the specific point of time
Great article. Good points on JWT and how much attention it gets while not being the complete solution some make it out to be. I think you are also making a good point about shiny new technology in general. It happens a lot where something comes out and becomes the new big thing and it gets misrepresented as something it is not.
Thanks for all the responses. Love the community here. Some interesting points and discussion.
I just hope this article might make people consider if they are using JWT to solve a specific problem for their application rather than just using it by default :) Especially people new to web development using a "starter" or doing a course that only shows them JWT in local storage.
Quoting joelnet - "Doing JWT right is hard." !
A brand new approach regarding the usage of JWT, which is the combination of the two very famous security mechanisms JWT and TOTP for the first time in their digital lives.
check it out
Can't we revoke JWT in that case?
By no means a JWT advocate btw.
Then you have a stateful revocation list you have to make available to every server and JWT is no longer stateless.
Oh right, didn't think of that.
Article about JWT. Ctrl-F "PASETO". "No results found".
Am dissapoint.
github.com/paragonie/paseto
paseto.io
All good, but - what about "microservices" architecture? Where several servers cannot validate the cookie session? Do you have a solution other than JWT?
Assuming you need the JWT for user properties because of your decoupled stateless architecture, just have another property on the JWT that holds a key.
Assuming you have a layer in your architecture that all your microservices use for config etc. Redis for example.
The value for that key in Redis could be the token.
This is an odd misconception I keep seeing about microservice architectures. Typically you have a gateway where requests arrive. The gateway verifies the session and forward the user context that it verified to any other systems it needs to contact.
This is how all the big companies that came up with the notion of microservices like Google and Facebook work.
Branca
tuupola / branca-spec
Authenticated and encrypted API tokens using modern crypto
Branca Token
Authenticated and encrypted API tokens using modern crypto.
What?
Branca is a secure easy to use token format which makes it hard to shoot yourself in the foot. It uses IETF XChaCha20-Poly1305 AEAD symmetric encryption to create encrypted and tamperproof tokens. Payload itself is an arbitrary sequence of bytes. You can use for example a JSON object, plain text string or even binary data serialized by MessagePack or Protocol Buffers.
Although not a goal, it is possible to use Branca as an alternative to JWT. Also see getting started instructions.
This specification defines the external format and encryption scheme of the token to help developers create their own implementations. Branca is closely based on Fernet specification.
Design Goals
Token Format
Branca token consists of header, ciphertext and an authentication tag. Header consists of version, timestamp and nonce. Putting…
'makes it hard to shoot yourself in the foot', now you need the secret on the client to decrypt?