Flask Decorators for Application Session Handling
Introduction
Flask is a lightweight and powerful web framework for Python. One of its most useful features is decorators, which allow us to modify the behaviour of functions in a reusable way. When building web applications, authentication and session management are critical components. Flask decorators easily handle login, logout, and session management efficiently.
In this article, we will explore how decorators work in Flask and how they can be used to manage user authentication and session handling with code examples.
Understanding Decorators in Flask
In Flask, decorators are functions that wrap around another function to modify its behaviour. They are typically used to add pre-processing or post-processing logic to routes.
A basic decorator in Python looks like this:
from functools import wraps
def my_decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
print("Before function call")
result = f(*args, **kwargs)
print("After function call")
return result
return decorated_function
@my_decorator
def say_hello():
print("Hello!")
say_hello()
#Output:
#Before function call
#Hello!
#After function call
Now, let’s see how we can use decorators in Flask for authentication.
Implementing Login Required Decorator
We can create a decorator to protect certain routes and ensure that only authenticated users can access them. This decorator will check if a user is logged in before allowing access to the route.
Code Example:
from flask import Flask, session, redirect, url_for, request, jsonify
from functools import wraps
app = Flask(__name__)
app.secret_key = "supersecretkey"
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'user' not in session:
return redirect(url_for('login'))
return f(*args, **kwargs)
return decorated_function
@app.route('/')
def home():
return "Welcome to the Flask App!"
@app.route('/dashboard')
@login_required
def dashboard():
return f"Hello, {session['user']}! Welcome to your dashboard."
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['user'] = request.form['username']
return redirect(url_for('dashboard'))
return '''<form method="post">Username: <input type="text" name="username"><br><input type="submit"></form>'''
Explanation:
login_required
Decorator: Checks if 'user' exists in the session.- If the user is not logged in: Redirects them to the
/login
page. - If logged in: Proceed to the requested route.
session
dictionary: Stores user data temporarily.login
Route: Handles login by storing the username in the session and redirecting to the dashboard.dashboard
Route: Protected bylogin_required
, only accessible after login.
Implementing Logout Functionality
We also need a way for users to log out and end their session. We can create a /logout
route to handle this.
Code Example:
@app.route('/logout')
def logout():
session.pop('user', None)
return redirect(url_for('home'))
Explanation:
session.pop('user', None)
: Removes the user from the session.- Redirects to the home page after logout.
Enhancing Security with Session Handling
To ensure security, you can add the following measures:
- Session Expiration: Automatically log out users after a period of inactivity.
- Secure Cookies: Store session cookies securely to prevent tampering.
- CSRF Protection: Prevent Cross-Site Request Forgery attacks.
Code Example for Session Expiration:
from datetime import timedelta
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
@app.route('/set_session')
def set_session():
session.permanent = True
session['user'] = "JohnDoe"
return "Session set for user JohnDoe"
Explanation:
session.permanent = True
: Marks the session as permanent.PERMANENT_SESSION_LIFETIME
: Sets session timeout to 30 minutes.
Conclusion
Flask decorators provide an elegant way to manage login, logout, and session handling. The login_required
decorator ensures that only authenticated users can access specific routes, while session handling enhances security and user experience.
By leveraging Flask’s session and decorators, you can build robust authentication mechanisms in your web applications.
Happy coding!