Session and Cookie Management in Flask
Following our guide on Building a Simple CRUD App with Flask and SQLAlchemy, this article explains Session and Cookie Management in Flask. HTTP is a stateless protocol, meaning each request is independent. Sessions and cookies allow us to store information across multiple requests from the same user.
📚 Prerequisites
- A running Flask application.
- Understanding of the request-response cycle.
🎯 Article Outline: What You'll Master
- ✅ Foundational Theory: The difference between cookies and sessions.
- ✅ Core Implementation: Using Flask's
sessionobject to store data. - ✅ Practical Application: Building a simple login system that remembers the user.
- ✅ Best Practices: Securely managing session data.
🧠 Section 1: The Core Concepts of Cookies and Sessions
- Cookies: Small pieces of data stored on the client's browser. They are sent with every request to the server.
- Sessions: Data stored on the server. The client is given a session ID (usually in a cookie) which is used to retrieve the session data on each request. Flask's sessions are client-side sessions, meaning the session data is stored in a cryptographically signed cookie on the client.
To use sessions in Flask, you must set a secret_key.
💻 Section 2: Deep Dive - Implementation and Walkthrough
Let's see how to use the session object.
2.1 - Setting and Getting Session Data
# app.py
from flask import Flask, session, redirect, url_for, request
app = Flask(__name__)
app.secret_key = 'your_very_secret_key' # Set a secret key
@app.route('/')
def index():
if 'username' in session:
return f'Logged in as {session["username"]}'
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
Step-by-Step Code Breakdown:
app.secret_key: This is required to sign the session cookie.session['username'] = ...: We store the username in thesessionobject, which behaves like a dictionary.if 'username' in session:: We check if a user is logged in by looking for theusernamekey in the session.session.pop('username', None): This removes theusernamefrom the session, effectively logging the user out.
🛠️ Section 3: Project-Based Example: A Simple View Counter
Let's build a simple application that counts how many times a user has visited a page.
# app.py
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'another_secret_key'
@app.route('/counter')
def counter():
if 'visits' in session:
session['visits'] = session.get('visits') + 1
else:
session['visits'] = 1
return f"Number of visits: {session['visits']}"
if __name__ == '__main__':
app.run(debug=True)
Walkthrough:
- Each time the
/counterroute is accessed, we increment thevisitsvalue in the session. session.get('visits')is used to safely get the value, returningNoneif it doesn't exist (although in this logic, we handle that with theif/else).
🔬 Section 4: A Deeper Dive: How Flask's Session Works
Flask's session is a "client-side" session. This means the session data is serialized, signed with the secret_key, and then stored in a cookie on the user's browser. When the user makes another request, the cookie is sent back, and Flask verifies the signature before deserializing the data into the session object.
Advantages:
- No server-side storage needed.
- Scales well with multiple servers.
Disadvantages:
- Session data is visible to the user (though not modifiable without the secret key).
- Cookies have a size limit (around 4KB).
✨ Section 6: Best Practices and Anti-Patterns
Best Practices:
- Use a long, random, and secret
secret_key. Do not commit it to version control. Load it from an environment variable. - Don't store large amounts of data in the session.
- Don't store sensitive data in the session if you can avoid it.
Anti-Patterns:
- Using a predictable
secret_key. - Storing objects in the session that are not JSON-serializable.
💡 Conclusion & Key Takeaways
You've learned how to use sessions in Flask to store data across requests, enabling features like user logins.
Let's summarize the key takeaways:
- Sessions are used to maintain state in a stateless protocol.
- Flask's
sessionobject is easy to use but requires asecret_key. - Flask uses client-side sessions, which have their own pros and cons.
Challenge Yourself: Combine the login system with the CRUD app, so only logged-in users can add to-do items.
➡️ Next Steps
In the next article, "Blueprints in Flask: Modularizing your application", we will learn how to structure larger Flask applications.
Glossary
- Cookie: A small piece of data stored on the client's browser.
- Session: A way to store data on the server (or in a signed cookie) across multiple requests.
- Stateless Protocol: A protocol where each request is independent and has no knowledge of previous requests.