Flask Cookies
Cookies are small pieces of data the browser stores on a user's computer and sends back with every request to the same domain. While sessions use cookies internally, Flask also lets you set and read cookies directly for use cases that do not fit the session model.
Cookies vs Sessions
| Feature | Cookies | Sessions |
|---|---|---|
| Stored at | Browser only | Browser (as a cookie) + server |
| Tamper-proof | No (user can edit) | Yes (signed by Flask) |
| Expiry control | Full control | Controlled via PERMANENT_SESSION_LIFETIME |
| Use for | Preferences, tracking tokens | Login state, cart, user identity |
| Size limit | ~4 KB per cookie | ~4 KB total for signed cookie |
Setting a Cookie
Cookies attach to the response object, not the return statement. Create a response with make_response() first, then call .set_cookie() on it:
from flask import Flask, make_response, request
@app.route('/set-theme')
def set_theme():
theme = request.args.get('theme', 'light')
response = make_response(f'Theme set to: {theme}')
response.set_cookie('theme', theme, max_age=60*60*24*30) # 30 days
return responseset_cookie() Parameters
| Parameter | Description | Example |
|---|---|---|
key | Cookie name | 'theme' |
value | Cookie value | 'dark' |
max_age | Lifetime in seconds | 2592000 (30 days) |
expires | Exact expiry datetime | datetime(2025, 1, 1) |
secure | Send only over HTTPS | True |
httponly | Block JavaScript access | True |
samesite | Cross-site request protection | 'Lax' |
Reading a Cookie
from flask import request
@app.route('/')
def home():
theme = request.cookies.get('theme', 'light')
return render_template('home.html', theme=theme)request.cookies is a dictionary of all cookies the browser sent with the request. Use .get() with a default value — the cookie may not exist on a user's first visit.
Deleting a Cookie
Browsers delete cookies when they expire. To delete one immediately, set its expiry to a time in the past:
@app.route('/reset-theme')
def reset_theme():
response = make_response(redirect(url_for('home')))
response.delete_cookie('theme')
return responsedelete_cookie() sets the cookie's max_age to 0, which tells the browser to remove it immediately.
Cookie Flow Diagram
First visit:
Browser ──GET /──▶ Flask
Flask sets cookie ──▶ Browser stores: theme=dark
Second visit:
Browser ──GET / + Cookie: theme=dark──▶ Flask
Flask reads: request.cookies.get('theme') = 'dark'
Practical Example: Language Preference
@app.route('/set-language/<lang>')
def set_language(lang):
if lang not in ['en', 'fr', 'es', 'de']:
lang = 'en'
response = make_response(redirect(url_for('home')))
response.set_cookie('lang', lang, max_age=60*60*24*365, httponly=True)
return response
@app.route('/')
def home():
lang = request.cookies.get('lang', 'en')
return render_template('home.html', lang=lang)Security Best Practices
- Set
httponly=Trueto prevent JavaScript from reading the cookie — this blocks XSS attacks from stealing it - Set
secure=Truein production so the cookie only travels over HTTPS - Never store passwords, credit card numbers, or sensitive personal data in cookies
- Use cookies for non-sensitive preferences; use sessions for authentication state
Summary
Cookies store small data strings in the browser that persist across visits. Set them with response.set_cookie() and read them from request.cookies. Always set httponly=True and secure=True in production. Use cookies for user preferences like theme and language, and reserve sessions for sensitive state like login identity.
