Flask Sessions

A session stores data about a user across multiple requests. HTTP is stateless — each request arrives as if the server has never seen the user before. Sessions solve this by saving small pieces of data between visits, like whether a user is logged in or what items are in their cart.

The Hotel Key Card Analogy

When you check into a hotel, the front desk gives you a key card. The card does not contain your room number — it contains a code the hotel system recognizes. When you swipe the card, the system looks up your room. Flask sessions work the same way: the browser holds a session cookie (the key card), Flask looks up session data on the server side (the room assignment).

Browser stores:  session cookie (encrypted ID)
Flask stores:    session data keyed to that ID

Request arrives:
  Browser sends cookie ──▶ Flask decrypts ──▶ reads session data

How Flask Sessions Work

Flask stores session data in a signed cookie on the browser. The data is encoded and signed with your app's SECRET_KEY. Users can see the session data (it is Base64-encoded), but they cannot tamper with it — the signature breaks if they modify the contents.

Setting Up Sessions

Sessions require a secret key. Set it once in your app config:

app.config['SECRET_KEY'] = 'your-very-secret-key'

In production, use a long random string and load it from an environment variable. A quick way to generate one:

python -c "import secrets; print(secrets.token_hex(32))"

Writing to the Session

from flask import Flask, session, redirect, url_for

@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    # verify credentials here ...
    session['username'] = username
    session['logged_in'] = True
    return redirect(url_for('dashboard'))

session behaves like a Python dictionary. Assign a key to store data. Flask saves it to the signed cookie automatically at the end of the request.

Reading from the Session

@app.route('/dashboard')
def dashboard():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    username = session.get('username', 'Guest')
    return f'<h1>Welcome, {username}!</h1>'

Deleting Session Data

@app.route('/logout')
def logout():
    session.pop('username', None)
    session.pop('logged_in', None)
    return redirect(url_for('home'))

# Or clear everything at once:
@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('home'))

Shopping Cart Example

@app.route('/cart/add/<int:product_id>')
def add_to_cart(product_id):
    cart = session.get('cart', [])
    if product_id not in cart:
        cart.append(product_id)
    session['cart'] = cart
    session.modified = True   # tell Flask the session changed
    return redirect(url_for('cart'))

@app.route('/cart')
def cart():
    cart_ids = session.get('cart', [])
    products = Product.query.filter(Product.id.in_(cart_ids)).all()
    return render_template('cart.html', products=products)

Set session.modified = True when you modify a mutable object (like a list or dictionary) inside the session. Flask tracks simple assignments automatically, but not mutations inside nested objects.

Session Lifetime

from datetime import timedelta

app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)

@app.route('/login', methods=['POST'])
def login():
    session.permanent = True   # use the lifetime setting above
    session['username'] = request.form.get('username')
    return redirect(url_for('dashboard'))

By default, sessions expire when the browser closes. Setting session.permanent = True keeps the session alive for the duration set in PERMANENT_SESSION_LIFETIME.

Session Security Notes

  • Never store passwords or sensitive data in sessions
  • Store only the user's ID; look up their data from the database on each request
  • Use a strong, random SECRET_KEY and keep it private
  • Rotate the secret key if you suspect it has been exposed (this invalidates all existing sessions)

Summary

Flask sessions store small amounts of user-specific data between requests using a signed cookie. Write to the session with session['key'] = value, read with session.get('key'), and clear with session.pop() or session.clear(). Sessions require a SECRET_KEY. Store only lightweight identifiers in sessions and load full user data from the database as needed.

Leave a Comment

Your email address will not be published. Required fields are marked *