Sessions & Cookies

Reviewed & published by Brayan K

A session is a per-user store that remembers data across requests, and a cookie is the small piece of browser-stored data Flask uses to make that possible — together they're how a site keeps you logged in.

Part of the free Flask course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

In this lesson you'll store data in the session object, read it back on later requests, set your own cookies directly, and understand why a secret_key is essential.

What You'll Learn in This Lesson

1 Storing Data in the Session

HTTP is stateless — each request arrives with no memory of the last one. The session object fixes that. It behaves like a dictionary you can write to in one request and read from in the next, scoped to a single user.

Because Flask stores the session in a signed cookie, you must set app.secret_key so users can't tamper with it. The example below logs a user in by saving their name to the session, then reads it back on the home page.

# app.py — remember a user with the session object
from flask import Flask, session, redirect, url_for

app = Flask(__name__)
app.secret_key = "change-me-in-production"   # signs the session cookie

@app.route("/login/<username>")
def login(username):
    # Write to the session like a dictionary
    session["user"] = username
    return redirect(url_for("home"))

@app.route("/")
def home():
    # Read it back on a later request
    user = session.get("user")
    if user:
        return f"Logged in as {user}."
    return "You are not logged in."

# The test client keeps cookies between requests, like a browser:
with app.test_client() as client:
    print(client.get("/").data.decode())            # You are not logged in.
    client.get("/login/ada")                          # stores user in session
    print(client.get("/").data.decode())            # Logged in as ada.

# ✅ Expected output:
# You are not logged in.
# Logged in as ada.

On the first request there's no session, so you see "You are not logged in." After visiting the login route, the session remembers the user and the home page greets them by name.

2 Logging Out: Clearing the Session

Logging a user out means removing their data from the session. Use session.pop("key", None) to drop a single value, or session.clear() to wipe everything.

The example below adds a logout route that clears the stored user and redirects home. After logout, the home page reports that nobody is signed in.

# app.py — log a user out by clearing the session
from flask import Flask, session, redirect, url_for

app = Flask(__name__)
app.secret_key = "dev-secret"

@app.route("/login/<username>")
def login(username):
    session["user"] = username
    return redirect(url_for("home"))

@app.route("/logout")
def logout():
    session.pop("user", None)   # remove just the user; session.clear() wipes all
    return redirect(url_for("home"))

@app.route("/")
def home():
    user = session.get("user")
    return f"Hello, {user}!" if user else "Nobody is logged in."

with app.test_client() as client:
    client.get("/login/grace")
    print(client.get("/").data.decode())   # Hello, grace!
    client.get("/logout")
    print(client.get("/").data.decode())   # Nobody is logged in.

# ✅ Expected output:
# Hello, grace!
# Nobody is logged in.

3 Setting Cookies Directly

Sometimes you want a plain cookie rather than the session — for example to remember a theme preference. Build a response with make_response(...), call response.set_cookie(name, value), and read it later with request.cookies.get(name).

The example below stores a theme cookie on one route and reads it back on another, returning the saved theme or a default.

# app.py — set and read a cookie directly
from flask import Flask, request, make_response

app = Flask(__name__)

@app.route("/set-theme/<theme>")
def set_theme(theme):
    response = make_response(f"Theme set to {theme}.")
    # Store a cookie in the browser for one week (max_age in seconds)
    response.set_cookie("theme", theme, max_age=60 * 60 * 24 * 7)
    return response

@app.route("/theme")
def show_theme():
    # Read the cookie back; default to 'light' if it's not set
    theme = request.cookies.get("theme", "light")
    return f"Current theme: {theme}"

with app.test_client() as client:
    print(client.get("/theme").data.decode())       # Current theme: light
    client.get("/set-theme/dark")                     # stores the cookie
    print(client.get("/theme").data.decode())       # Current theme: dark

# ✅ Expected output:
# Current theme: light
# Current theme: dark

🔬 Sessions vs Cookies at a Glance

TaskCode
Save to sessionsession["user"] = name
Read from sessionsession.get("user")
Log outsession.pop("user", None)
Set a cookieresponse.set_cookie("theme", "dark")
Read a cookierequest.cookies.get("theme")

🎯 Your Turn: Fill in the Blanks

Complete the visit counter below. Replace each ___ so it stores a count in the session and increments it on each request.

# 🎯 YOUR TURN: replace each ___ to build a visit counter
from flask import Flask, session

app = Flask(__name__)
app.___ = "dev-key"                 # what attribute signs the session cookie?

@app.route("/")
def counter():
    # Read the current count, defaulting to 0
    count = session.___("count", 0)  # which method reads with a default?
    count += 1
    session["count"] = count          # store the new count back in the session
    return f"You have visited {count} time(s)."

with app.test_client() as client:
    print(client.get("/").data.decode())   # ...1 time(s)
    print(client.get("/").data.decode())   # ...2 time(s)

Common Errors & Quick Reference

❌ RuntimeError: The session is unavailable because no secret key was set

You used session without a key. Set app.secret_key = "..." once after creating the app. Use a long, random value in production.

❌ My cookie or session "doesn't stick" between requests

Cookies are tied to the browser. Tools like curl drop them unless you tell them to persist. In tests, reuse one app.test_client() so cookies carry over like a real browser.

TaskCode
Enable sessionsapp.secret_key = "..."
Store a valuesession["key"] = value
Clear everythingsession.clear()
Run the appflask run

🏆 Mini Challenge: A Login Gate

Build a protected page that only logged-in users can see.

# 🏆 Mini Challenge: a login-gated page
from flask import Flask, session, redirect, url_for

app = Flask(__name__)
app.secret_key = "dev-secret"

@app.route("/login/<username>")
def login(username):
    session["user"] = username
    return redirect(url_for("secret"))

@app.route("/secret")
def secret():
    if "user" not in session:
        return redirect(url_for("login", username="guest"))
    return f"Top secret data for {session['user']}!"

with app.test_client() as client:
    # Not logged in -> redirected to login, which logs in 'guest'
    print(client.get("/secret", follow_redirects=True).data.decode())
    client.get("/login/ada")
    print(client.get("/secret").data.decode())   # Top secret data for ada!

❓ Frequently Asked Questions

Lesson complete — your app can remember its users!

You stored and cleared data in the session, set and read raw cookies, and learned why app.secret_key keeps sessions safe.

Practice quiz

How does the Flask session object behave in your code?

  • Like a file handle
  • Like a dictionary
  • Like a database cursor
  • Like a list

Answer: Like a dictionary. session behaves like a dictionary you read from and write to.

Where does Flask store the session data by default?

  • In a server-side file
  • In the URL
  • In a signed cookie
  • In a database table

Answer: In a signed cookie. Flask serializes the session into a signed cookie sent to the browser.

What must you set for sessions to work?

  • app.debug
  • app.config['DB']
  • app.name
  • app.secret_key

Answer: app.secret_key. app.secret_key signs the session cookie; without it session use raises an error.

How do you safely read a session value with a default?

  • session.get("user")
  • session.read("user")
  • session.fetch("user")
  • session.value("user")

Answer: session.get("user"). session.get("user") returns the value or None/default if absent.

How do you remove a single value to log a user out?

  • session.delete("user")
  • session.pop("user", None)
  • session.remove("user")
  • del session

Answer: session.pop("user", None). session.pop("user", None) removes just that key.

Which call wipes everything from the session?

  • session.reset()
  • session.empty()
  • session.clear()
  • session.drop()

Answer: session.clear(). session.clear() removes all stored session data.

How do you set a cookie directly on a response?

  • request.set_cookie(...)
  • cookie.add(...)
  • session.cookie(...)
  • response.set_cookie(name, value)

Answer: response.set_cookie(name, value). Build a response with make_response and call response.set_cookie(name, value).

How do you read a cookie the browser sent back?

  • request.cookies.get("theme")
  • session.cookie("theme")
  • response.cookies["theme"]
  • request.form.get("theme")

Answer: request.cookies.get("theme"). request.cookies.get("theme") reads an incoming cookie value.

Why does Flask sign the session cookie?

  • To compress it
  • So users can't tamper with its contents
  • To encrypt the database
  • To speed up requests

Answer: So users can't tamper with its contents. Signing lets Flask detect tampering with the cookie's contents.

What property of HTTP makes sessions necessary?

  • It is encrypted
  • It only supports GET
  • It is stateless — each request has no memory of the last
  • It caches everything

Answer: It is stateless — each request has no memory of the last. HTTP is stateless, so sessions add per-user memory across requests.

Continue this course

Frequently asked questions

What is a session in Flask?

A session is a per-user store that persists across requests. Flask's session object behaves like a dictionary; you read and write keys, and Flask saves the data in a signed cookie so the same user sees it on their next request.

What is the difference between a session and a cookie?

A cookie is a small piece of data stored in the browser and sent back with every request. Flask's session is built on a single signed cookie: you work with a dictionary in Python, and Flask handles writing and reading the cookie for you.

Why does session require a secret_key?

Flask signs the session cookie with app.secret_key so users can't tamper with its contents. Without a secret key, any attempt to use session raises an error. Use a long, random value and keep it out of source control in production.

How do I set my own cookie directly?

Build a response with make_response(...) and call response.set_cookie('name', 'value'). The browser stores it and sends it back; you read it later with request.cookies.get('name'). Sessions are easier for most cases, but raw cookies give you full control.