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

Sponsored

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:

  1. A user visits your Flask route.

  2. Your app calls response.set_cookie('key', 'value') to attach a cookie to the response.

  3. The browser stores the cookie (key-value pair) locally.

  4. On every subsequent request to your domain, the browser automatically includes that cookie in the Cookie header.

  5. 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/aliceCookie set to alice. Go home (the response includes Set-Cookie: username=alice header)

  • 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=0 in set_cookie as an alternative to delete_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 session uses 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 librariesFlask-Session extends 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 call set_cookie on a plain string return.

  • The cookie is being set on a different domain — check the domain parameter of set_cookie.

  • Browser privacy settings block third-party cookies — test with curl -v to see the Set-Cookie header.

Cookie value is None when reading?

  • The path in set_cookie might be different from the request path — use path='/' to make it available site-wide.

  • The cookie expired — max_age was too short or you deleted it.

  • You're testing with curl but don't include -b to 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=True for session-related cookies to prevent XSS from stealing them.

  • Use secure=True in 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 call set_cookie on 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

  1. Use Flask's session instead of raw cookies for data that must be tamper-proof — it signs the cookie content server-side.
  2. Store serialized JSON in a cookie for complex data, but watch the 4KB size limit and encode special characters.
  3. Leverage Flask-Session to 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-Cookie and returned by the browser with every request.
  • In Flask, use make_response to get a response object, then call set_cookie to attach a cookie.
  • Read cookies with request.cookies.get('name') — it safely returns None if absent.
  • Control cookie lifetime with max_age, restrict access with httponly, secure, and samesite flags.
  • 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.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.