Back to Blog
Python

Python Flask Cookies and Sessions: Implementation and Security

python flask cookies and sessions: Learn how to set and read cookies, use signed sessions, configure session behavior, and secure Flask applications against common coo...

FlaskCookiesSessionsWeb SecurityPython
Illustration of a Flask application using cookies and signed sessions to maintain user state across HTTP requests.

When you build a Flask application that needs to remember a user across requests, you typically reach for cookies and sessions. Flask provides a built-in session object that stores data in a signed cookie on the client side. This article explains how python flask cookies and sessions work, how to configure them, and what security tradeoffs you need to consider.

How Cookies Work in Flask

Cookies are small pieces of data sent by the server in a Set-Cookie header. The browser stores them and sends them back with every subsequent request to the same domain. Flask exposes incoming cookies through request.cookies and lets you attach cookies to a response with response.set_cookie().

A cookie has attributes that control its behavior: max_age (or expires), path, domain, secure, httponly, and samesite. These attributes determine how long the cookie lives, which paths it applies to, and whether JavaScript can read it.

Setting and Reading Cookies

Here is a minimal Flask route that sets a cookie and reads it back:

from flask import Flask, request, make_response app = Flask(__name__) @app.route('/set-cookie') def set_cookie(): resp = make_response('Cookie set') resp.set_cookie('username', 'alice', max_age=3600, httponly=True) return resp @app.route('/read-cookie') def read_cookie(): username = request.cookies.get('username') return f'Username: {username}'

The set_cookie method accepts keyword arguments for all standard cookie attributes. Setting httponly=True prevents client-side JavaScript from accessing the cookie, which reduces the risk of XSS-based cookie theft. For production, you should also set secure=True to ensure the cookie is only sent over HTTPS.

Flask Sessions: Signed Client-Side Storage

Flask's session object is a dict-like structure that stores data in a cookie. Unlike traditional server-side sessions, Flask sessions are client-side by default: the session data is serialized, signed with your app's SECRET_KEY, and sent to the browser. The browser sends it back on each request, and Flask verifies the signature to detect tampering.

Here is a basic session example:

from flask import Flask, session app = Flask(__name__) app.secret_key = 'your-secret-key' # In production, use a random, environment-variable value @app.route('/login') def login(): session['user_id'] = 42 return 'Logged in' @app.route('/profile') def profile(): user_id = session.get('user_id') return f'User ID: {user_id}'

The session data is signed, not encrypted. Anyone can read the contents of the cookie, but they cannot modify it without knowing the secret key. This means you should never store sensitive information like passwords or credit card numbers in a Flask session.

Configuring Session Behavior

Flask provides several configuration variables that control session cookies. You set them via app.config:

app.config.update( SECRET_KEY='a-strong-random-value', SESSION_COOKIE_NAME='myapp_session', SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SECURE=True, # Requires HTTPS SESSION_COOKIE_SAMESITE='Lax', PERMANENT_SESSION_LIFETIME=timedelta(days=7), SESSION_REFRESH_EACH_REQUEST=True )

PERMANENT_SESSION_LIFETIME controls how long a session lasts when you set session.permanent = True. SESSION_REFRESH_EACH_REQUEST extends the cookie's expiration on every request, which is useful for keeping active users logged in but can be a security concern if you want absolute timeouts.

Security Considerations for Cookies and Sessions

Because Flask sessions are signed but not encrypted, the main security concern is tampering. An attacker who does not know your SECRET_KEY cannot forge a valid session, but they can read the data. Always use a strong, randomly generated secret key and rotate it if you suspect a leak.

For cookies you set manually, always consider the secure, httponly, and samesite attributes. samesite helps mitigate CSRF attacks by restricting when the cookie is sent. For example, SAMESITE='Strict' prevents the cookie from being sent on cross-site requests, while 'Lax' allows top-level navigation.

If you need to store sensitive data, use a server-side session backend such as Flask-Session with Redis or a database. This keeps the data off the client and only stores a session ID in the cookie.

When to Use Cookies vs Sessions

In Flask, the choice between cookies and sessions depends on what you are storing and whether you need server-side control.

Use CaseCookieFlask Session
Data visibilityVisible to clientVisible to client (signed)
Data sizeLimited to ~4KBLimited by cookie size
Tamper resistanceNone by defaultSigned, requires secret key
Server-side invalidationNot possibleNot possible (client-side)
Sensitive dataNot suitableNot suitable

Use a plain cookie for non-sensitive, short-lived values like a theme preference. Use Flask sessions when you need a signed, tamper-evident container for user identity or preferences. For anything sensitive, use a server-side session store.

Common Pitfalls and Limitations

One common mistake is forgetting to set app.secret_key. Without it, Flask raises an error when you try to use sessions. Another issue is storing too much data in a session. Browsers limit cookie size to around 4KB, so large session payloads will be truncated or rejected.

Session data is serialized using JSON, so you can only store JSON-serializable types. If you need to store custom objects, convert them to a serializable form first.

Secret key rotation is another challenge. If you change SECRET_KEY, all existing sessions become invalid, forcing users to log in again. Plan for this by using a key management strategy that allows gradual rotation.

Production Considerations

In production, always run your Flask app behind HTTPS and set SESSION_COOKIE_SECURE=True. Use a strong SECRET_KEY from an environment variable or a secrets manager, never hardcode it. Consider using a server-side session backend for applications that require logout, session revocation, or store sensitive data.

If you use multiple Flask processes, client-side sessions work without shared storage, but server-side sessions require a shared backing store like Redis. Also, be aware that the Set-Cookie header is only sent once per response; if you modify the session after the response starts, Flask will raise an error.

python flask cookies and sessions: Practical Usage and Code | RYUSLOG DEV