In short
HTTP forgets you after every single request. Sessions are how a server remembers 'this is Aman, he logged in ten minutes ago' without asking for his password on every click.
A server-side mechanism for remembering a logged-in user across requests, typically by storing session data server-side (or in Redis) and identifying it via a cookie.

Think of it like this
The cloakroom token
At a mall cloakroom you hand over your bag and get a small brass token. The token itself is worthless; the counter keeps the bag. Show the token, get your bag. A session cookie is that token. The server keeps your login details, and the cookie just points to them.
Watch it happen
Log in once, stay remembered
POST /login
1/6You send your email and password, just once.
The big ideas
What you need to know
The cookie holds only an id
A long random session id, nothing else. The real data stays safely on the server.
Store sessions centrally
Keep them in Redis or your database, so any server behind the load balancer can read them.
Lock the cookie down
Set HttpOnly, Secure and SameSite=Lax, so scripts can't read it and other sites can't easily send it.
Easy to revoke
Delete the session and the user is out instantly. That's the big win over plain JWTs.
See it in code
Walk through the code
1import session from "express-session";2import { RedisStore } from "connect-redis";3 4app.use(session({5 store: new RedisStore({ client: redis }),6 secret: process.env.SESSION_SECRET!,7 resave: false,8 saveUninitialized: false,9 cookie: { httpOnly: true, secure: true, sameSite: "lax", maxAge: 7 * 24 * 60 * 60 * 1000 },10}));11 12app.post("/login", async (req, res) => {13 const user = await checkPassword(req.body.email, req.body.password);14 if (!user) return res.status(401).json({ error: { code: "BAD_LOGIN" } });15 req.session.regenerate(() => { req.session.userId = user.id; res.sendStatus(204); });16});1/3Sessions live in Redis. resave and saveUninitialized set to false avoid writing empty sessions.
redis is a connected node-redis client. In TypeScript, add userId to the SessionData interface with declaration merging.
Save yourself the pain
Common mistakes
Oops
Using the default in-memory session store in production.
Do this instead
It leaks memory and forgets everyone on restart. Use Redis or a database-backed store.
Oops
Keeping the same session id before and after login.
Do this instead
Call req.session.regenerate() on login, so an attacker who planted an id can't ride your session.
Your mission
Log in with sessions
Quick check
In a session-based login, where is the user's login data kept?
Go deeper
- 1Implement session-based login using `express-session`.
- 2Store sessions in Redis instead of memory so they survive server restarts.
- 3Compare session-based auth to token-based (JWT) auth and their different scaling trade-offs.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.