Why Storing JWTs in localStorage Is a Security Nightmare for Modern Apps
What's the best way to do authentication in modern applications

I break down the heated debate on where to store authentication tokens, revealing why localStorage and in-memory variables leave your users vulnerable to XSS attacks. I explain how HTTP-only cookies with Secure and SameSite flags offer the only reliable defense, forcing attackers to act only within a live session rather than stealing a permanent skeleton key.
Anyone who tells you an HTTP-only cookie prevents XSS is confused or selling something.
- padjo
> So the boring 2005 design wins.
As an old guy reading this I had a lot of wtf moments during the setup. Then I laughed pretty hard when we eventually got to this line. Like there's a reason we invented cookies and all mature web frameworks use them for auth.
- StrauXX
localStorage is very much fine and arguably superior to cookies for authentication tokens. First of all, once you have achieved JS execution on a target origin, you can send requests, open up malicious "login" prompts and generally control everything the user sees and does. The article mentions this, but plays it down with no good arguments.
Much more importantly however, is that the cookie standards are a mess! The complexity of cookie default behaviour, their flags, scopes, differences in their SOP (cookies ignore ports for example, so https://example.com:443 and https://example.com:8443 share their cookies) are huge. Research papers have been written in this. And don't even get started on differentials between browsing engines.
This huge complexity of cookies opens up a whole class of authentication attacks where bad (or just weirdly) configured cookies can be stolen cross origin.
localStorage on the other hand is practically impossible to get wrong.
- homebrewer
Cookies can be encrypted and signed and contain whatever information you want, not just some random token that has to be looked up in the database to be actually useful.
This is what aspnet core does by default if you enable cookie-based authentication. Gives you the best of both worlds.