What is the difference between session-based authentication and JWT authentication?
Sessions store user state on the server and give the browser only a session id cookie. JWTs carry signed user claims in the token itself, so the server stores nothing, but revoking a token before it expires is harder.
Explain it simply
Sessions are like a cloakroom token. You get a small numbered token, and the cloakroom (server) remembers whose coat it is. The token itself says nothing. JWT is like a signed ID card: the guard reads it, trusts the signature, and needs no register.
| Point | Sessions | JWT |
|---|---|---|
| Where state lives | server (memory, Redis, DB) | inside the token |
| What the client holds | random session id, in a cookie | signed token |
| Logout or revoke | delete the session, instant | wait for expiry, or keep a deny-list |
| Scaling | needs a shared store across servers | stateless, any server can verify |
| Size per request | tiny | larger |
| Fits | traditional websites, admin panels | APIs, mobile apps, microservices |
Example
// session style (express-session, with a store like Redis in production)
app.post("/login", async (req, res) => {
const user = await verifyCredentials(req.body);
req.session.userId = user.id; // server remembers
res.sendStatus(204);
});
// JWT style
app.post("/login", async (req, res) => {
const user = await verifyCredentials(req.body);
const token = jwt.sign({ sub: user.id }, process.env.JWT_SECRET, { expiresIn: "15m" });
res.json({ token }); // client remembers
});Neither is always better. A simple website with one server is easier and safer with sessions. Many teams adopt JWT too early and then build revocation lists, which brings back state.
What to say in the interview
"Sessions keep state on the server and are easy to revoke; JWTs are self-contained and stateless but hard to invalidate early. I choose by need: sessions for a classic web app, short-lived JWTs with refresh tokens for APIs and mobile clients."
Common mistakes
- Thinking JWT is automatically more secure.
- Using the default in-memory session store in production.