A cookie is a small piece of data a site gives the browser with an answer. The browser keeps it and sends it back, on its own, with every later request to that site. That's how a website stays logged in without adding an Authorization header to each request.
The express-session package uses such a cookie to give each browser a session: an object the shop keeps for that browser, which every route finds in req.session. The cookie holds only the session's id, signed with a secret, so the browser can read the cookie but can't change it without the server noticing. You use the session like any object. In TypeScript, a declare module "express-session" line tells which properties a session may hold. For example, two routes could remember a shopper's favorite color:
declare module "express-session" { interface SessionData { color: string } }
app.post("/color", (req: Request, res: Response) => {
req.session.color = req.body.color;
res.json({ color: req.session.color });
});
app.get("/color", (req: Request, res: Response) => {
res.json({ color: req.session.color || "blue" });
});
In this lesson, /login also puts the token in the session, and currentUser uses it when a request brings no Authorization header. When the header is there, it still wins. The tests use one client that keeps its cookies, like a browser:
GET /me (no header, no cookie yet) → 401 {"error": "Login required"}
POST /login {"email": "ana@example.com", "password": "secret123"} → 200 {"token": "…"}
GET /me (no header) → 200 {"email": "ana@example.com", "id": 2, "role": "customer"}
GET /welcome (no header) → 200 Welcome back, ana@example.com!
POST /products {"name": "Desk", "price": 120} (no header) → 403 {"error": "Admins only"}
POST /login {"email": "admin@example.com", "password": "admin-pass-123"} → 200 {"token": "…"}
POST /products {"name": "Desk", "price": 120} (no header) → 201 {"id": 9, "name": "Desk", "price": 120}
GET /me (Bearer Ana's token) → 200 {"email": "ana@example.com", "id": 2, "role": "customer"}
GET /me (no header) → 200 {"email": "admin@example.com", "id": 1, "role": "admin"}
Your task: turn sessions on with app.use(session({ ... })) and the secret "dev-secret-123", put the token in req.session.token at login, and let currentUser take the token from the session when the header gives none.
Assignment
Follow the Coding Tutorial to keep users logged in with a session and its signed cookie.
Hint
Without the header, header.replace("Bearer ", "") gives the empty text "": that's when to read req.session.token || "". The || "" matters for a request whose session has no token yet, and it keeps token a string. Declare token with let, since it may get a new value.
Free plan: 30 tutor messages. PRO is unlimited.
