Both JWT and Session have to validated on each request
You can store your JWT token in a secure cookie (so javascript has no access to it)
Even with JWT you most likely still store "session data" (then a login last happened from which country/ip/device) on the server for security/audit purposes
JWT is more like a data format so you can still do session authentication with JWT
Both JWT and session cookies can be stateless. Persisting some light state serverside is often worthwhile though, supporting features like a user logging out of a public kiosk from a different device later, or enforcing a short session expiration policy but extending it while in active use. (And can have great performance using Redis or some other k/v store.) But if you really don't want to hit redis, the cookie value can be signed like JWT or fully encrypted.
Good points but I don't think the conclusion is at all blurry. JWT is overused, session cookies are easier to use and more secure. JWT was popularized as an auth workaround for serverless/jamstack and by delegated auth vendors (like auth0) so it seems like a modern/trendy choice to a coder who doesn't look closely, but in reality it's a bad choice in most scenarios. Avoid JWT unless there's a specific and compelling need for it.
Preventing javascript from accessing auth-related secrets is a valuable security feature that session cookies offer with the HttpOnly option. You can lock them down further with the Host, SameSite, and Secure options. Web frameworks like Django/Laravel/Spring/Rails/etc make them even easier to implement. Stuffing JWT into one is fine, but then there's little point to it and in practice they're left insecure.
That’s why I was very careful to use the word “virtually”. ;) The point is that a JWT is easy to inspect, whereas an encrypted JWT is much harder to inspect. However, I must stress that sensitive information should not be sent within a JWT claim, so JWEs are theoretically unnecessary. The point behind a JWT is that sending a User UUID, is deemed acceptable. Modifying the User UUID value, inside the JWT, will cause the authentication phase of the JWT, on the server, to fail.
So it is preferable to send the User UUID, in a JWT, rather than sending it, as an endpoint param.
This article does a great job of explaining some tricky tech concepts in a way that's easy to understand. It talks about how authentication is about proving who you are, and authorization is about what you're allowed to do or see on a website or app. Then it compares two different ways websites keep track of who you are - one using something called JWT and the other using sessions. The explanation is really clear, making these tech ideas much easier to grasp, especially if you're not already an expert in web security. It's a helpful read for anyone trying to get a handle on how online security works.
Great tutorial. Regarding session based auth, you say:
Performance Issues at Scale: The dependency on database interactions for every session validation can introduce latency, particularly for high-traffic applications.
I think this is probably negligible, because normally a REST API request will be requesting data from the database, anyway? 🤔
For me, JWT is most suitable (about securities and reusuability) but more hard to program. Session is more easy. Most Framework (like Django), supports natively Session authentication, it is suitable for short deadline.
I'd say the scalability point is moot, without the underlying details on how you do your architecture. You can use a separate domain, load balancers and servers (or even an edge environment like cloudflare workers) to scale authentication requests. Obviously you will have to configure the right CORS and Content-Security-Policy headers as well.
Without seeing how in practice a concrete solution is implemented -> you can't say if one is more scalable than the other.
Sure, and if done well monoliths are more scalable than bad microservices. Every article on internet would be "it depends on the situation" but that would be a book not a blog :)
What I learnt in the past years using both approach on different apps is that:
Use JWT between trusted entities in a trusted environment, e.g. authorising requests between services, create short-living tokens only for the length of possible longest response time.
Use session-based authentication where you need to communicate between untrusted sources and store a refresh token to each session with which you can generate the short living tokens to sign the request in the system internally.
Benefits:
You can force close a session any time if you detect any abusive or unexpected behaviour of the user or on case of password change, etc. With JWT you should blacklist the token and make a check in every round you use that, which kills the JWT token's "stateless-ness".
Exposed JWTs can be used for short time, reduced security risk.
You don't need to refresh tokens on UI periodically as it expires. (❤️)
The boundary is much more blurry
JWT is more like a data format so you can still do session authentication with JWT
Valid points. To me main difference is stateless vs stateful and most other differences stem from that very nature.
Both JWT and session cookies can be stateless. Persisting some light state serverside is often worthwhile though, supporting features like a user logging out of a public kiosk from a different device later, or enforcing a short session expiration policy but extending it while in active use. (And can have great performance using Redis or some other k/v store.) But if you really don't want to hit redis, the cookie value can be signed like JWT or fully encrypted.
Good points but I don't think the conclusion is at all blurry. JWT is overused, session cookies are easier to use and more secure. JWT was popularized as an auth workaround for serverless/jamstack and by delegated auth vendors (like auth0) so it seems like a modern/trendy choice to a coder who doesn't look closely, but in reality it's a bad choice in most scenarios. Avoid JWT unless there's a specific and compelling need for it.
Preventing javascript from accessing auth-related secrets is a valuable security feature that session cookies offer with the HttpOnly option. You can lock them down further with the Host, SameSite, and Secure options. Web frameworks like Django/Laravel/Spring/Rails/etc make them even easier to implement. Stuffing JWT into one is fine, but then there's little point to it and in practice they're left insecure.
In what situations would jwt be absolutely required?
For those of you, interested, I have created a JWE library:
forgebox.io/view/JWTSignEncrypt
Normally, a JWT is just base64 encoded. A JWE is an encrypted JWT, which makes it virtually impossible to crack.
Tks by share.
Everything is "virtually impossible to crack" until it is cracked. :D
That’s why I was very careful to use the word “virtually”. ;)
The point is that a JWT is easy to inspect, whereas an encrypted JWT is much harder to inspect. However, I must stress that sensitive information should not be sent within a JWT claim, so JWEs are theoretically unnecessary.
The point behind a JWT is that sending a User UUID, is deemed acceptable. Modifying the User UUID value, inside the JWT, will cause the authentication phase of the JWT, on the server, to fail.
So it is preferable to send the User UUID, in a JWT, rather than sending it, as an endpoint param.
Next blog post: How to store JWTs securely :-)
Nice suggestion. Onto it, let’s open that can of worms 😅
Here that auth0, one of the biggest third party provider says about it
auth0.com/docs/secure/security-gui...
This article does a great job of explaining some tricky tech concepts in a way that's easy to understand. It talks about how authentication is about proving who you are, and authorization is about what you're allowed to do or see on a website or app. Then it compares two different ways websites keep track of who you are - one using something called JWT and the other using sessions. The explanation is really clear, making these tech ideas much easier to grasp, especially if you're not already an expert in web security. It's a helpful read for anyone trying to get a handle on how online security works.
Great tutorial. Regarding session based auth, you say:
I think this is probably negligible, because normally a REST API request will be requesting data from the database, anyway? 🤔
IMO additional database calls will happen only after authentication is done, to prevent DDOS attacks, so would be done sequentially not in parallel.
And one man's negligible might be another man's JIRA ticket :)
For me, JWT is most suitable (about securities and reusuability) but more hard to program. Session is more easy.
Most Framework (like Django), supports natively Session authentication, it is suitable for short deadline.
This is a very informative and clear summary of JWT and sessions 👍 keep up the good work!
This was nice, It really helped me to understand.
Thanks!
I'd say the scalability point is moot, without the underlying details on how you do your architecture.
You can use a separate domain, load balancers and servers (or even an edge environment like cloudflare workers) to scale authentication requests. Obviously you will have to configure the right CORS and Content-Security-Policy headers as well.
Without seeing how in practice a concrete solution is implemented -> you can't say if one is more scalable than the other.
Sure, and if done well monoliths are more scalable than bad microservices. Every article on internet would be "it depends on the situation" but that would be a book not a blog :)
What I learnt in the past years using both approach on different apps is that:
Benefits:
Very well put. Useful information
I would call it "the confrontation of recent years"
I can’t take either side, but it was interesting to read
You can use session with redis for better performance.
Useful!