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.
Spring's session (HttpSession) is a small store of values for one visitor, kept on the server. The browser gets a cookie that holds only the session's id, a long random code, so it can't read or change what the session holds. A method gets the session as a parameter and uses setAttribute and getAttribute. For example, two routes could remember a shopper's favorite color:
@PostMapping("/color")
Object setColor(HttpSession session, @RequestBody Map<String, Object> data) {
session.setAttribute("color", data.get("color"));
return Map.of("color", data.get("color"));
}
@GetMapping("/color")
Object getColor(HttpSession session) {
return Map.of("color", Objects.requireNonNullElse(session.getAttribute("color"), "blue"));
}
In this lesson, login also stores 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: at login, store the token in the session under "token", 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 cookie.
Hint
Without the header, header.replace("Bearer ", "") gives the empty text "": test it with token.equals(""), and that's when to read request.getSession().getAttribute("token"). It gives null when the session has no token yet, so swap that for "" with Objects.requireNonNullElse.
Free plan: 30 tutor messages. PRO is unlimited.
