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.
Flask's session is a dictionary kept in such a cookie. Flask signs it with app.secret_key, so the browser can read the cookie but can't change it without the server noticing. You use it like any dictionary. For example, two routes could remember a shopper's favorite color:
@app.post("/color")
def set_color():
session["color"] = request.get_json()["color"]
return jsonify({"color": session["color"]})
@app.get("/color")
def get_color():
return jsonify({"color": session.get("color", "blue")})
In this lesson, /login also puts the token in the session, and current_user 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: set app.secret_key to "dev-secret-123", put the token in session["token"] at login, and let current_user take the token from the session when the header gives none.
Assignment
Follow the Coding Tutorial to keep users logged in with a signed session cookie.
Hint
Without the header, header.replace("Bearer ", "") gives the empty text "": that's when to read session.get("token", ""). The default "" matters for a request that has no cookie yet.
Free plan: 30 tutor messages. PRO is unlimited.
