python
53 lines · 8 steps
How signed remember-me cookies work in Flask
A Flask login route issues a tamper-proof persistent auth cookie and validates it on later requests.
Explained by
highlit
1from datetime import timedelta
2
3from flask import Blueprint, current_app, make_response, redirect, request, url_for
4from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
5from werkzeug.security import check_password_hash
6
7auth = Blueprint("auth", __name__)
8
9REMEMBER_COOKIE = "remember_token"
10REMEMBER_MAX_AGE = timedelta(days=30)
11
12
13def _serializer():
14 return URLSafeTimedSerializer(current_app.secret_key, salt="remember-me")
15
16
17@auth.post("/login")
18def login():
19 user = User.query.filter_by(email=request.form["email"].lower()).first()
20 if user is None or not check_password_hash(user.password_hash, request.form["password"]):
21 return redirect(url_for("auth.login_form", error="invalid"))
22
23 login_user(user)
24
25 response = make_response(redirect(url_for("dashboard.index")))
26
27 if request.form.get("remember"):
28 token = _serializer().dumps({"uid": user.id, "v": user.token_version})
29 response.set_cookie(
30 REMEMBER_COOKIE,
31 token,
32 max_age=int(REMEMBER_MAX_AGE.total_seconds()),
33 httponly=True,
34 secure=not current_app.debug,
35 samesite="Lax",
36 )
37
38 return response
39
40
41def load_user_from_remember_cookie():
42 token = request.cookies.get(REMEMBER_COOKIE)
43 if not token:
44 return None
45 try:
46 data = _serializer().loads(token, max_age=int(REMEMBER_MAX_AGE.total_seconds()))
47 except (BadSignature, SignatureExpired):
48 return None
49
50 user = User.query.get(data["uid"])
51 if user is None or user.token_version != data["v"]:
52 return None
53 return user
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Signing cookies with a secret key and salt makes them tamper-evident without server-side session storage.
- 2Embedding a token version lets you invalidate all outstanding remember-me cookies by bumping one field.
- 3Setting httponly, secure, and samesite hardens auth cookies against XSS and CSRF theft.
Related explainers
python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI()
Building a WebSocket chat with FastAPI
websockets
broadcast
connection-management
Intermediate
9 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
python
import secrets from django.contrib.auth import authenticate, login from django.core.cache import cache
Two-factor login with OTP in Django
two-factor-auth
one-time-passwords
caching
Intermediate
9 steps
python
import re from functools import total_ordering from typing import Optional
Parsing and comparing semantic versions
regex
operator-overloading
sorting
Intermediate
7 steps
ruby
require "openssl" require "base32" class TOTP
How TOTP one-time codes work in Ruby
hmac
authentication
totp
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/how-signed-remember-me-cookies-work-in-flask-explained-python-6a5a/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.