← Back to news

Stop Using JWTs

gist.github.com|304 points|173 comments|by dzonga|Jun 16, 2026

🛑 Stop Using JWTs

TL;DR: You should not use JSON Web Tokens (JWTs) to maintain user login sessions. They weren't built for this, they introduce security vulnerabilities, and there is a far superior alternative: standard cookie-based sessions.

For a deeper dive, I highly recommend this video presentation. Note: The talk glosses over some details like CSRF protection, and while it mentions "valid" JWT use cases at the end, those can usually be handled more securely by tools like PASETO.

Additionally, please store your tokens in localStorage stop using localStorage or sessionStorage for any authentication credentials. See this guide for more: Please stop using local storage.


⚠️ Why JWTs are the Wrong Choice

The push toward JWTs often stems from a misunderstanding of their purpose. Here is why they fail as session managers:

  1. Incorrect Lifespan: The JWT specification is intended for extremely short-lived tokens, typically: Duration5 minutes\text{Duration} \le 5\text{ minutes}
  2. The "Stateless" Myth: Truly stateless authentication is not feasible if you want it to be secure. To handle tokens safely, you need state. If you're already maintaining a data store, it is more efficient to simply store the session data there.
  3. Security Flaws: Security experts generally distrust the JWT specification. The original spec allowed for the creation of fraudulent tokens and likely contains other systemic errors. For a technical breakdown, see this analysis.
  4. Inefficiency: Using a JWT to simply hold a session ID is less flexible and more bloated than a standard session cookie, offering zero actual advantage.

Comparison: JWTs vs. Session Cookies

FeatureJWT (for Sessions)Session Cookies
StateClaims to be statelessStateful (Server-side)
RevocationDifficult/Impossible without stateInstant (Delete from DB)
SecuritySpec is widely distrustedIndustry standard
ComplexityHigh (Key mgmt, rotation)Low (Built into frameworks)

🛠️ The Right Way: Session Management

Session technology isn't "new," which is why you don't see as many trendy blog posts about it. However, almost every web framework has a built-in session implementation that is easy to toggle on.

Implementation in Node.js/Express

Since Express is modular, you'll need a few pieces:

  • Middleware: express-session
  • Store: A connector to your database (e.g., connect-session-knex for PostgreSQL, MySQL, or SQLite).
// Conceptual example of session setup
const session = require('express-session');
const KnexSessionStore = require('connect-session-knex')(session);

app.use(session({
  store: new KnexSessionStore({ client: 'pg', connection: dbConfig }),
  secret: 'your-secure-secret',
  resave: false,
  saveUninitialized: false,
  cookie: { secure: true, httpOnly: true }
}));

How Sessions Flow


❓ Common Counter-Arguments

"But I have a stateless API!"

The Reality: Users and their permissions are state. If your app has a database, you have state.

  • Shared State: You can keep your API services "stateless" by storing sessions in a shared database (like Redis or Postgres). All API nodes check the same DB.
  • Cross-Host Transfers: If you need to move a user between different hosts, use a one-time token to link the new connection to the existing session.
  • Auth Transfers: This is where a tool like a JWT (a signed, encrypted, one-time-use token) is actually appropriate.

"Why is everyone recommending JWTs then?"

It's a result of the "hype cycle." When the spec was released, a few engineers wrote excited blog posts. These were often misunderstood and echoed by others who didn't fully grasp the security implications. Because traditional sessions are "boring," they aren't written about in tutorials for "hip" stacks (React, Angular, Node), leaving JWTs to dominate the search results.


✅ Final Recommendations

  • Stop using JWTs for long-term authentication.
  • Stop storing tokens in localStorage.
  • Switch to server-side sessions with secure cookies.
  • Use PASETO if you absolutely need a short-lived, signed token.
  • Read joepie91's gist to master session mechanics.

Community Contributors

@samsch @vcarl @HosMercury @Longwater1234 @ManasN @kishoreandra