Flask-Session
Flask-Session is an official extension for Flask that provides support for server-side session management. Instead of storing session data directly in client-side cookies (which can be size-limited and less secure), it stores it on the server using various backends like Redis, Memcached, FileSystem, MongoDB, SQLAlchemy, or DynamoDB. The current version is 0.8.0, and it is actively maintained by the Pallets organization, ensuring regular updates and compatibility with Flask. [1, 5, 15, 16]
Warnings
- breaking The default session serialization format changed from `pickle` to `msgspec` in version 0.7.0. While 0.7.0 attempts to convert existing `pickle` sessions upon read/write, `pickle` support will be entirely removed in version 1.0.0. Any un-migrated `pickle` sessions will be cleared upon access in 1.0.0. [5, 7, 10]
- deprecated The `SESSION_USE_SIGNER` configuration option and `FileSystemSessionInterface` were deprecated in version 0.7.0. `FileSystemSessionInterface` is replaced by `CacheLibSessionInterface` which uses `cachelib` under the hood. [7, 10]
- gotcha It is crucial to set `app.config["SECRET_KEY"]` when using Flask-Session, even though sessions are server-side. This secret key is used to cryptographically sign the session ID cookie that is sent to the client, preventing tampering and ensuring session integrity. [8, 12]
- gotcha Flask-Session's `Session` class is for initializing the extension with your Flask application. To access or modify the current session data within your routes, you must import and use `flask.session`, which is Flask's built-in session proxy. Attempting to use the `Session` instance directly for data access will not work as expected. [3, 4]
- gotcha The `PERMANENT_SESSION_LIFETIME` configured in Flask's app config (e.g., `app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)`) is used by Flask-Session to set the expiration time for the *server-side session data*, not just the client-side cookie. This applies regardless of whether `SESSION_PERMANENT` is set to `True` or `False`. [2, 10]
Install
-
pip install flask-session -
pip install 'flask-session[redis]' # For Redis backend pip install 'flask-session[cachelib]' # For CacheLib backend (replaces FileSystem) pip install 'flask-session[mongodb]' # For MongoDB backend pip install 'flask-session[sqlalchemy]' # For SQLAlchemy backend pip install 'flask-session[dynamodb]' # For DynamoDB backend
Imports
- Session
from flask_session import Session
- session
from flask import session
Quickstart
import os
from flask import Flask, session, redirect, url_for
from flask_session import Session
from redis import Redis
app = Flask(__name__)
# Configuration for server-side sessions
app.config["SECRET_KEY"] = os.environ.get("FLASK_SECRET_KEY", "super-secret-key-that-should-be-random-and-long")
app.config["SESSION_TYPE"] = "redis"
app.config["SESSION_PERMANENT"] = False # Set to True for permanent sessions
# Configure Redis client (replace with your Redis connection details)
# For production, consider using environment variables for host/port/password
app.config["SESSION_REDIS"] = Redis(host=os.environ.get("REDIS_HOST", "localhost"), port=6379, db=0)
# Initialize Flask-Session
Session(app)
@app.route('/')
def index():
if 'username' in session:
return f'Hello, {session["username"]}! <a href="/logout">Logout</a>'
return 'You are not logged in. <a href="/login">Login</a>'
@app.route('/login')
def login():
# Simulate a login, in a real app this would involve forms and authentication
session['username'] = 'testuser'
return redirect(url_for('index'))
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)