Content Index
- What is a session in Flask and what is it for?
- Key operations with Flask Session
- Considerations for mobile apps (Flutter / React Native)
- ⚠️ Note on object serialization in the session
- Differences between session and cookies in Flask
- ⚙️ Configuring the session in a Flask project
- Practical examples of using session in Flask
- Maintaining user data after login
- ️ Implementing a shopping cart with Flask Session
- Flask-Session extension: server-side sessions
- Installation and configuration of Flask-Session
- Usage with Redis and other storage options
- Best practices and security in Flask Session
- ️ Avoiding exposure of sensitive data
- ⏱️ Controlling session expiration (session timeout)
- Configuring secure cookies (SESSION_COOKIE_SECURE)
- Storing arrays and multiple elements in the Flask session
- Conclusion
- ❓ Frequently Asked Questions about Flask Session (FAQ)
When developing a web application with Flask, an inevitable moment arrives: we need to maintain user information between requests. Whether it is knowing who logged in, what is in their shopping cart, or what preferences they configured. This goes far beyond flash messages in Flask, which only persist for a single request.
That is where the session in Flask comes into play: a lightweight and very practical tool to manage temporary user data, either on the server side or the client side, depending on the configuration you choose.
In essence, the session serves to store information related to a specific user throughout their navigation. Data such as their name, unique identifier, or preferences can live in the session without needing to query them on every request. We will use it extensively in later chapters, especially in the authentication flow.
A classic use case, and perhaps the most common one, is the shopping cart: each product the user adds is recorded in the session until they checkout or close the browser.
Something important to keep in mind: session data is temporary. The session has a configured or implicit expiration date, and it will eventually expire.
Additionally, the session changes dynamically throughout the user's lifecycle: it is created when they log in, updated when any data changes, and destroyed when they log out or complete a purchase.
What is a session in Flask and what is it for?
A session is a temporary storage space that keeps information between different HTTP requests. In Flask, each user has their own session, identified by a secure cookie signed with a secret key.
For example, when a user successfully logs in, their name or ID is saved in the session to recognize them on every subsequent visit. In my case, I usually use it for exactly that: storing authenticated user data without having to ask for it again on every page or make an extra database query.
To use the session, it is necessary to set a secret key (secret_key), which Flask uses to cryptographically sign the cookie's content. This ensures that the client cannot manipulate the session data. This key must be defined from the beginning of the project, either directly in the main file or in your custom configuration file in Flask:
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'Key operations with Flask Session
To manage your sessions efficiently, these are the most common operations you will use in your routes and controllers:
| Action | Code |
|---|---|
| Read data | session.get('key') |
| Write / Save | session['key'] = 'value' |
| Delete data | session.pop('key', None) |
| Clear entire session (Logout) | session.clear() |
Considerations for mobile apps (Flutter / React Native)
If you are consuming your Flask API from a mobile application like Flutter or React Native, remember that although native apps do not usually have the same CORS restrictions as a web browser, when testing on emulators or integrated webviews, cookie and session handling may behave differently.
Best practices for sessions on mobile:
- Do not blindly trust cookies: Some mobile platforms manage cookies volitily or directly do not persist them between sessions. For mobile apps, consider using
JWTtokens instead of cookie-based sessions. - Configure preflight correctly: If your mobile app sends custom headers, make sure your Flask-CORS configuration allows
OPTIONSrequests. - Mandatory HTTPS with secure cookies: If you use
SESSION_COOKIE_SECURE = True, your API must be served over HTTPS; otherwise, the session cookie will not be sent and the session will not be maintained on mobile devices.
⚠️ Note on object serialization in the session
Careful! Never attempt to store complex objects—such as SQLAlchemy instances or database models—directly in the session.
Flask serializes session content to JSON format to store it in the cookie. If you try to store an object that is not serializable, you will get an error like "Object of type X is not JSON serializable". The rule is simple: store only primitive data (strings, numbers, lists, dictionaries) or structures you can manually convert to JSON.
Differences between session and cookies in Flask
Although both allow storing information between HTTP requests, there are key differences that determine when to use one or the other:
| Aspect | Cookie | Session |
|---|---|---|
| Data location | User browser (plain text) | Server (or encrypted in signed cookie) |
| Security | Lower — user can read it | Higher — cryptographically signed |
| Duration | According to configured expiration date | Expires automatically or when calling session.clear() |
⚙️ Configuring the session in a Flask project
Before using the session, you need to configure the secret_key that Flask uses to sign cookies and prevent tampering. Without it, Flask will raise an error when attempting to access the session object.
You can define it directly in your main file:
from flask import Flask
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'To use the session in any route, import the session object from Flask:
from flask import sessionWith that available, you can save data in the session just like in a Python dictionary:
session['username'] = 'user'Retrieving a value is just as direct:
session['username']And to delete a specific piece of data without destroying the entire session, use session.pop():
session.pop('username', None)The second argument None prevents a KeyError from being raised if the key does not exist, which makes this pattern safe even if the user had previously logged out.
Practical examples of using session in Flask
To see it all together, here is a test module with three routes covering the complete cycle of a session: creating it, checking it, and deleting it:
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'clave_super_secreta'
@app.route('/test/session/set')
def test_session_set():
session['username'] = 'user'
return 'Session created for user'
@app.route('/test/session/check')
def test_session_check():
if 'username' in session:
return f'Authenticated user: {session["username"]}'
return 'No active session'
@app.route('/test/session/pop')
def test_session_pop():
session.pop('username', None)
return 'Session deleted'Test the three routes in order: first /test/session/set to create the session, then /test/session/check to verify it, and finally /test/session/pop to delete it. This gives you a clear idea of a session's lifecycle in Flask.
Maintaining user data after login
When a user successfully logs in, assigning their data to the session object is enough. This allows identifying them anywhere in the application throughout their active session, without needing to query the database on every request.
@app.route('/login', methods=['POST'])
def login():
user = User.query.filter_by(email=request.form['email']).first()
if user and user.check_password(request.form['password']):
session['user_id'] = user.id
session['username'] = user.name
return redirect(url_for('dashboard'))
return 'Invalid credentials', 401The usual recommendation—and the one I follow—is to store only the user_id in the session and query the database when you need the full user details. This reduces cookie size and ensures data is always up to date.
️ Implementing a shopping cart with Flask Session
In another project, I used the session to store a list of products simply:
session['cart'] = ['Book A', 'Book B']And upon checkout, it was enough to clear that data from the session:
session.pop('cart', None)For a more complex cart (with quantities, prices, variants, etc.), you can store a list of dictionaries. Always remember to reassign the variable in the session after modifying it, since Flask does not automatically detect internal changes in mutable objects (see the arrays section below).
Flask-Session extension: server-side sessions
By default, Flask stores the entire session in a signed client cookie. This works well in small applications, but has a limit: cookies have a maximum size of 4 KB. If you need to store more data or want the session to persist on the server with greater control, the Flask-Session extension is the solution.
Installation and configuration of Flask-Session
$ pip install Flask-Sessionfrom flask_session import Session
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)With SESSION_TYPE = 'filesystem', session data is saved in files on the server instead of the client cookie. This allows you to store larger objects and have greater control over expiration.
Usage with Redis and other storage options
For distributed or larger-scale applications, you can use SESSION_TYPE = 'redis' and point to a Redis server:
import redis
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('redis://localhost:6379')
Session(app)Redis is ideal when you have multiple instances of your application running in parallel, as they all share the same session store. Other options available in Flask-Session are sqlalchemy, mongodb, and memcached.
Best practices and security in Flask Session
️ Avoiding exposure of sensitive data
Never store passwords, access tokens, or private information directly in the session. Use anonymous identifiers (like user_id) and, if you need to protect additional data, apply encryption before storing it.
⏱️ Controlling session expiration (session timeout)
You can configure the session lifetime using permanent_session_lifetime along with session.permanent = True:
from datetime import timedelta
app.permanent_session_lifetime = timedelta(minutes=30)
@app.route('/login')
def login():
session.permanent = True
session['user_id'] = user.idWithout session.permanent = True, the session expires upon closing the browser (browser session). With that line active, Flask respects the permanent_session_lifetime value and the session lasts for the configured time even if the user closes and reopens the browser.
Configuring secure cookies (SESSION_COOKIE_SECURE)
In production, always mark the session cookie as secure so it is only transmitted over HTTPS:
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'SESSION_COOKIE_HTTPONLY = True prevents client-side JavaScript from accessing the cookie, protecting against XSS attacks. SESSION_COOKIE_SAMESITE = 'Lax' reduces the risk of CSRF attacks in most scenarios.
Storing arrays and multiple elements in the Flask session
The session in Flask is not limited to strings or numbers: you can store lists, dictionaries, or any data structure that is serializable to JSON. This opens the door to more complex use cases, such as maintaining a list of active elements per user without needing a database.
Flask provides the session object, which behaves like a normal Python dictionary. You can import it directly from the framework:
from flask import sessionSaving multiple values in the session is as direct as this:
session['age'] = 30
session['name'] = "Andres"Now, there is an important detail when working with lists inside the session: Flask does not automatically detect internal changes in mutable objects. If you modify a list or dictionary that is already in the session, you must explicitly reassign it so Flask marks it as modified and updates the cookie. The correct pattern is this:
def addRoomSession(room):
if 'rooms' not in session:
session['rooms'] = []
rooms = session['rooms'] # 1. Get the list from the session
rooms.append(room) # 2. Modify the local list
session['rooms'] = rooms # 3. Reassign it so Flask detects the change
print(session['rooms'])
def removeRoomSession(room):
if 'rooms' not in session:
return
rooms = session['rooms']
rooms.remove(room)
session['rooms'] = roomsThe trick is in the reassignment at step 3. Without it, Flask might not save changes to the cookie because the object in memory is the same and the cookie is not marked as modified. An alternative is to manually set session.modified = True after any internal mutation, although explicit reassignment is clearer and more portable.
This code is part of my complete course on Flask, where we look at how to work with Flask-SocketIO and the concept of rooms, a real use case where the session plays a key role.
Conclusion
The session in Flask is an essential tool to maintain user data between requests without complicating the backend. Its combination of simplicity and security makes it perfect for managing logins, shopping carts, or any flow requiring temporary persistence.
If your project grows and the 4 KB cookie falls short, you can expand capacity with Flask-Session backed by Redis, ensuring scalability and total control over session data.
❓ Frequently Asked Questions about Flask Session (FAQ)
- What happens if the server restarts?
- Cookie-based sessions are maintained as long as the
secret_keydoes not change. Server-side sessions (filesystem, Redis) can be lost if you do not use persistent storage or if the process restarts without configured persistence.
- Cookie-based sessions are maintained as long as the
- Can I store complex objects in the session?
- Yes, but they must be serializable to JSON (lists, dictionaries, strings, numbers). SQLAlchemy objects or custom class instances are not directly serializable.
- How do I delete all session data at once?
- Use
session.clear()to clear the session completely. This is the most common way to implement logout in Flask.
- Use
- Is the session in Flask secure?
- Yes, as long as you use a robust and random
secret_key, enableSESSION_COOKIE_SECURE = Truein production (with HTTPS), and avoid storing sensitive data directly in the session.
- Yes, as long as you use a robust and random
- How do I decode a Flask session cookie?
- The session cookie is Base64 encoded and signed with the
secret_key, but not encrypted. You can view its content by decoding the part before the first dot usingbase64.b64decode(), but you cannot forge it without knowing the secret key. That is why it is critical that this key is complex and not exposed in public repositories.
- The session cookie is Base64 encoded and signed with the
- What is the difference between
session.pop()andsession.clear()?session.pop('key', None)deletes only the data with that key, leaving the rest of the session intact.session.clear()destroys the entire session at once, useful for implementing complete logout.
Recommendation: Store only the user identifier (
user_id) in the session and, on each request, query your database to get the rest of the details. This keeps data always up to date and the cookie small.
The next step: learn how to use forms in Flask with WTForms.