C.W.K.
Stream
Lesson 02 of 06 · published

Sessions vs Tokens — What's Actually In That Cookie

~15 min · sessions, jwt, cookies

Level 0Greenhorn
0 XP0/53 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

"Logged in" can mean wildly different things depending on what is in the cookie. Three patterns dominate, and each has a distinct failure mode.

PatternWhat is in the cookieServer storesRevocation
Session cookieRandom opaque token (e.g. 32 hex chars)Mapping token → user_id, expires_at, ip in DBDelete the row — instant
JWT (signed, stateless)Self-describing JSON + signatureNothingCannot truly revoke until expiry; needs a denylist
Bearer token (API key)Random string in Authorization headerDB row + scopesDelete the row

Why sessions win for solo apps

The PIN layer in this quest uses session cookies in a SQLite table. Reasons:

  • Instant revocation. "Revoke All" is one SQL DELETE. JWT requires a denylist that defeats the whole stateless point.
  • Tied to IP. Each session row stores the IP it was issued to; mismatched IP = invalid. Free anti-replay.
  • Visible in admin. You can list active sessions, see when they were issued, where from, when they expire.
  • Tiny. No external dependency; SQLite ships with Python.

Cookie flags that matter

FlagEffectDefault stance
HttpOnlyJavaScript cannot read the cookieAlways on — blocks XSS theft
SecureOnly sent over HTTPSOn in production; off only for localhost
SameSite=StrictCookie not sent on cross-site requestsOn for solo apps — you don't need cross-site flow
Max-AgeLifetime in secondsBounded — e.g. 30 days, never "infinite"

Code

Setting a hardened session cookie in FastAPI / Starlette·python
response.set_cookie(
    key="session",
    value=token,
    max_age=30 * 24 * 3600,    # 30 days
    httponly=True,            # JS can't read it
    secure=True,              # HTTPS only — turn off only for localhost dev
    samesite="strict",        # no cross-site sends
    path="/",
)

External links

Exercise

Open DevTools → Application → Cookies on one of your own apps and inspect the session cookie. Check: HttpOnly set? Secure set? SameSite value? Max-Age bounded? For each missing flag, fix it server-side and reload. Most browsers visually flag insecure cookies in the cookie inspector.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.