Set and read cookies in Flask
Learn how to set and read cookies in Flask with this hands-on Python web development tutorial. Understand the core concepts, follow step-by-step examples, and explore troubleshooting tips and common edge cases. Ideal for developers progressing through a structured learning path.
Focus: set and read cookies in flask
You've built a Flask app that responds to requests, but every visitor is anonymous — you can't tell a returning user from a first-time one. That's the pain this lesson solves: by the end, you'll be able to set and read cookies in Flask to remember users across requests. Cookies are the silent workhorses of the web — they power session logins, shopping carts, and personalized dashboards. In this hands-on lesson, you'll learn exactly how to write and read them in Flask, handle common pitfalls, and prepare for the next step: managing sessions securely.
The problem this lesson solves
Imagine you run a small Flask app that greets users with "Welcome!" every single time they visit. No memory, no personalization, no way to know if they've been here before. That's the default stateless nature of HTTP — each request is independent, and the server forgets everything once the response is sent.
This is a real problem for any web app that needs continuity. Without a mechanism to identify returning users, you can't:
-
Remember login state
-
Track preferences like theme or language
-
Store a shopping cart between page loads
-
Show personalized content based on past visits
Cookies solve this by letting the server send a small piece of data to the browser, which the browser stores and sends back with every subsequent request. In Flask, set_cookie and request.cookies give you a simple, built-in way to implement this — no external libraries needed.
Core concept / mental model
Think of cookies like a name tag given to each visitor when they enter a party. The first time someone walks in, you write their name on a sticker and hand it to them. Every time they come up to the snack table, they show the sticker, and you know exactly who they are. In web terms:
-
Server = the host of the party
-
Browser = the guest
-
Cookie = the name tag (a small text file)
-
Request = the guest approaching the table again
Here's the flow in words:
-
A user visits your Flask route.
-
Your app calls
response.set_cookie('key', 'value')to attach a cookie to the response. -
The browser stores the cookie (key-value pair) locally.
-
On every subsequent request to your domain, the browser automatically includes that cookie in the
Cookieheader. -
In Flask, you read it via
request.cookies.get('key').
Important: cookies are sent from the browser to the server automatically — you don't have to manually add them to each request. This is what makes them so convenient.
How it works step by step
Let's break down the process of setting and reading a cookie in Flask into clear steps.
Setting a cookie
To set a cookie, you need to modify the response object. Flask's make_response is the key here, because route functions normally just return strings — those don't have a set_cookie method.
Step 1: Import make_response
from flask import Flask, make_response, request
Step 2: Create a response object
resp = make_response(render_template('index.html'))
Step 3: Call set_cookie on the response
resp.set_cookie('username', 'alice', max_age=60*60*24) # 1 day
The first argument is the cookie name, the second is the value, and max_age controls how long the cookie lives in seconds.
Reading a cookie
When the browser sends a request, Flask parses the Cookie header and exposes it in request.cookies. You read it like a dictionary:
username = request.cookies.get('username')
If the cookie doesn't exist, .get() returns None — so you can safely handle missing cookies without raising a KeyError.
Putting it together
The full pattern is: on one route, set the cookie; on another (or the same) route, read it. This is the foundation for any stateful feature.
Hands-on walkthrough
Now let's build a complete example. We'll create a small Flask app that greets a user by name if they've set a cookie before, and allows them to set a new name via a URL parameter.
Example 1: Set and read a basic cookie
from flask import Flask, make_response, request
app = Flask(__name__)
@app.route('/')
def index():
# Read the cookie if it exists
username = request.cookies.get('username')
if username:
return f'Welcome back, {username}!' # <p> trim </p>
return 'Welcome, new visitor!'
@app.route('/set/<name>')
def set_name(name):
resp = make_response(f'Cookie set to {name}. <a href="/">Go home</a>')
resp.set_cookie('username', name, max_age=60*60*24) # 1 day
return resp
if __name__ == '__main__':
app.run(debug=True)
Expected output:
-
Visiting
/first time →Welcome, new visitor! -
Visiting
/set/alice→Cookie set to alice. Go home(the response includesSet-Cookie: username=aliceheader) -
Visiting
/again →Welcome back, alice!
Example 2: Cookie with expiry and secure flags
Real-world apps need finer control. Let's set a cookie that expires in 30 minutes and is only sent over HTTPS.
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/preferences')
def preferences():
resp = make_response("Preferences saved.")
# Expire in 30 minutes
resp.set_cookie(
'theme',
'dark',
max_age=1800, # seconds
httponly=True, # JS can't read it
secure=True, # only over HTTPS
samesite='Lax' # CSRF protection
)
return resp
Expected behavior: The browser stores theme=dark, and it's automatically attached to subsequent requests.
Example 3: Deleting a cookie (logging out)
To remove a cookie, set its expiry in the past.
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/logout')
def logout():
resp = make_response("Logged out.")
resp.delete_cookie('username')
return resp
Expected behavior: The Set-Cookie header now contains username=; Expires=Thu, 01 Jan 1970 ..., prompting the browser to delete it.
Pro tip: Use
max_age=0inset_cookieas an alternative todelete_cookie— it achieves the same effect in older browsers.
Compare options / when to choose what
Cookies aren't the only way to persist data in Flask. Here's a comparison to help you decide:
| Approach | Pros | Cons | Best use case |
|---|---|---|---|
| Cookies | Simple, built-in, client-side storage | Limited size (~4KB), visible to user, vulnerable to tampering | Non-sensitive preferences, anonymous tracking |
Session (Flask's session) |
Server-side storage, signed, secure | Requires a secret key, larger server state | Login state, sensitive user data |
| Database | Persistent, scalable, queryable | More setup, slower for every request | User accounts, long-term history |
When to choose cookies: If the data is small, non-sensitive, and needs to be available on the client side (like a theme preference), cookies are perfect. For anything that must be trusted — like user ID or permissions — use Flask's session instead, which signs cookies to prevent tampering.
Variations: Beyond basic cookies
-
Signed cookies — Flasks's
sessionuses signed cookies behind the scenes, preventing users from modifying values without knowing the secret key. -
JSON in cookies — Store complex data by serializing to JSON, but watch out for the 4KB size limit.
-
Third-party libraries —
Flask-Sessionextends the session to server-side stores like Redis, useful for large apps.
Troubleshooting & edge cases
Cookie not being set?
-
Forgot
make_response— you can't callset_cookieon a plain string return. -
The cookie is being set on a different domain — check the
domainparameter ofset_cookie. -
Browser privacy settings block third-party cookies — test with
curl -vto see theSet-Cookieheader.
Cookie value is None when reading?
-
The path in
set_cookiemight be different from the request path — usepath='/'to make it available site-wide. -
The cookie expired —
max_agewas too short or you deleted it. -
You're testing with
curlbut don't include-bto send back cookies.
Cookie value has unexpected characters?
- Cookies can't contain semicolons or commas — URL-encode or base64-encode values if needed.
Security concerns
-
Never store passwords or tokens directly in cookies — use sessions.
-
Always set
httponly=Truefor session-related cookies to prevent XSS from stealing them. -
Use
secure=Truein production over HTTPS.
What you learned & what's next
You've just learned the core idea behind set and read cookies in Flask: the server sends a Set-Cookie header, the browser stores and returns it, and request.cookies reads it. You practiced setting cookies with make_response().set_cookie(), reading them with request.cookies.get(), and even deleting them. You can now:
-
Explain the HTTP cookie flow from response to request
-
Set cookies with lifetime, path, and security flags
-
Read cookies safely and handle missing values
-
Choose between cookies, sessions, and databases based on the need
Most importantly, you understand why cookies are the bedrock of stateful web apps. The natural next step in your Python web development journey is Flask sessions — which build on cookies but add signing and server-side security. You'll learn how to store user login state without exposing it to tampering. Get ready!
Key takeaway: Cookies are simple but powerful. Master them, and you've unlocked the ability to make your Flask apps remember users — the first step toward real-world features like authentication and personalization.
Practice recap
Build a mini Flask app with two routes: /set that sets a cookie with your favorite color, and / that reads and displays it. Then add a /clear route that deletes the cookie. Test with your browser's developer tools or curl -v to see the Set-Cookie header in action.
Common mistakes
- Forgetting to use
make_response— you cannot callset_cookieon a string returned directly from a route; it raises AttributeError. - Not setting
path='/'on a cookie, so it's only sent to the specific URL path and appears 'missing' on other routes. - Assuming
request.cookies['key']will always exist — it raises a KeyError if missing; use.get()instead. - Storing sensitive data like passwords in plain cookies — they're visible and modifiable by the client.
- Testing in a browser with privacy settings that block third-party cookies, leading to unexpected 'cookie not saved' behavior.
Variations
- Use Flask's
sessioninstead of raw cookies for data that must be tamper-proof — it signs the cookie content server-side. - Store serialized JSON in a cookie for complex data, but watch the 4KB size limit and encode special characters.
- Leverage
Flask-Sessionto keep sessions server-side (e.g., Redis) for large-scale or high-security apps.
Real-world use cases
- A news site stores a user's selected theme ('dark'/'light') in a cookie to personalize the layout across visits.
- An e-commerce app tracks the items in your cart via a cookie so the cart persists even before you log in.
- A marketing platform uses cookies to track anonymous visitor behavior for analytics and A/B testing.
Key takeaways
- Cookies are small key-value pairs sent by the server in
Set-Cookieand returned by the browser with every request. - In Flask, use
make_responseto get a response object, then callset_cookieto attach a cookie. - Read cookies with
request.cookies.get('name')— it safely returnsNoneif absent. - Control cookie lifetime with
max_age, restrict access withhttponly,secure, andsamesiteflags. - Delete a cookie by setting its expiry in the past or using
response.delete_cookie(). - For sensitive data, prefer signed sessions over raw cookies to prevent tampering.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.