Authorization in Flask
Introduction
This article explains how to implement role-based access control and protect routes using decorators in Flask. Role-based access control ensures that only users with specific roles can access certain parts of the application.
Step 1: Setting Up Flask and SQLAlchemy
Start by installing Flask and SQLAlchemy:
pip install flask flask-sqlalchemy
Configure your Flask app:
from flask import Flask, redirect, url_for, request, flash from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SECRET_KEY'] = 'your_secret_key' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///roles.db' db = SQLAlchemy(app)
Step 2: Defining the User Model
Create a User model with a role field:
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) role = db.Column(db.String(20), nullable=False) db.create_all()
Example roles could include admin
, editor
, and viewer
.
Step 3: Creating Role-Based Access Control Decorators
Define a decorator to check the user's role before allowing access to a route:
from functools import wraps def role_required(required_role): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): # Simulate fetching the current user (replace with real logic) current_user = User.query.filter_by(username='example_user').first() if current_user and current_user.role == required_role: return func(*args, **kwargs) else: flash('Access denied. You do not have the required role.') return redirect(url_for('login')) return wrapper return decorator
Step 4: Protecting Routes
Use the decorator to restrict access to specific routes:
@app.route('/admin') @role_required('admin') def admin_page(): return 'Welcome, Admin! This is the admin page.' @app.route('/editor') @role_required('editor') def editor_page(): return 'Welcome, Editor! This is the editor page.' @app.route('/viewer') @role_required('viewer') def viewer_page(): return 'Welcome, Viewer! This is the viewer page.'
Step 5: Adding Users with Roles
Create a route to add new users with specific roles:
@app.route('/add-user', methods=['POST']) def add_user(): username = request.form.get('username') role = request.form.get('role') user = User(username=username, role=role) db.session.add(user) db.session.commit() flash('User added successfully!') return redirect(url_for('login'))
Form for adding users:
<form method="POST" action="/add-user"> Username: <input type="text" name="username"><br> Role: <select name="role"> <option value="admin">Admin</option> <option value="editor">Editor</option> <option value="viewer">Viewer</option> </select><br> <button type="submit">Add User</button> </form>
Step 6: Testing Role-Based Access Control
Start the Flask application, add users with different roles, and test accessing the protected routes. Ensure that only users with the correct roles can access specific pages.
Conclusion
Role-based access control allows you to secure your application by restricting access to routes based on user roles. By using decorators, you can easily enforce these restrictions and manage user permissions effectively.