Start learning free

LESSON 93 OF 188 · BACKEND: USERS AND SECURITY

Log Out

Practice

Logging out has to happen on the server. If only the browser forgot the token, anyone who had copied it could still use it. So POST /logout deletes the request's token from the tokens table. After that the shop doesn't know that token, and it gets 401 everywhere.

To delete the token, the route needs the token itself, not just the user: a user who logged in twice has two tokens. So the lines that find it (the header first, then the session) move into a function of their own, current_token(), which both current_user() and logout call.

A DELETE is a query like the others, followed by a commit. For example, a route that empties a user's cart could run:

db.execute("DELETE FROM cart_items WHERE user_id = ?", (user["id"],))
db.commit()

In the tests, Ana logs in twice: first on her phone (token <phone>, sent in the header), then in the browser (token <token>, also kept in the cookie). Logging out in the browser must not log the phone out:

GET /me  (cookie)  →  200  {"email": "ana@example.com", "id": 2, "role": "customer"}
POST /logout  (cookie)  →  200  {"message": "Logged out"}
GET /me  (cookie)  →  401  {"error": "Login required"}
GET /me  (Bearer <token>)  →  401  {"error": "Login required"}
GET /me  (Bearer <phone>)  →  200  {"email": "ana@example.com", "id": 2, "role": "customer"}
POST /logout  (Bearer <phone>)  →  200  {"message": "Logged out"}
GET /me  (Bearer <phone>)  →  401  {"error": "Login required"}

Your task: move the token-finding lines into current_token(), rewrite current_user() on top of it, and add POST /logout behind @login_required: it deletes this request's token, empties the session and answers {"message": "Logged out"}.


Assignment
Follow the Coding Tutorial to add a /logout route that really logs the user out.


Hint
Delete the token before you call session.clear(): current_token() reads the session. logout takes user because @login_required passes it, even though it doesn't use it.


STEP 1 OF 11
    Ctrl + Enter to check