下面是一个基于 Flask 和 Bootstrap 的后台权限管理方案,包含用户认证、角色管理和权限控制等功能。
核心组件
- Flask - 作为后端框架
- Bootstrap - 前端UI框架
- Flask-Login - 用户会话管理
- Flask-SQLAlchemy - 数据库ORM
- Flask-WTF - 表单处理
- Flask-Principal 或自定义装饰器 - 权限控制
数据库模型设计
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
db = SQLAlchemy()
# 用户-角色 多对多关联表
user_roles = db.Table('user_roles',
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('role_id', db.Integer, db.ForeignKey('roles.id'))
)
# 角色-权限 多对多关联表
role_permissions = db.Table('role_permissions',
db.Column('role_id', db.Integer, db.ForeignKey('roles.id')),
db.Column('permission_id', db.Integer, db.ForeignKey('permissions.id'))
)
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))
active = db.Column(db.Boolean, default=True)
roles = db.relationship('Role', secondary=user_roles,
backref=db.backref('users', lazy='dynamic'))
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def has_role(self, role_name):
return any(role.name == role_name for role in self.roles)
def has_permission(self, permission_name):
return any(permission.name == permission_name
for role in self.roles
for permission in role.permissions)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
description = db.Column(db.String(128))
permissions = db.relationship('Permission', secondary=role_permissions,
backref=db.backref('roles', lazy='dynamic'))
class Permission(db.Model):
__tablename__ = 'permissions'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
description = db.Column(db.String(128))
endpoint = db.Column(db.String(128)) # 对应的路由端点
权限控制实现
方案1: 使用装饰器
from functools import wraps
from flask import abort
from flask_login import current_user
def permission_required(permission_name):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.has_permission(permission_name):
abort(403) # 无权限
return f(*args, **kwargs)
return decorated_function
return decorator
def admin_required(f):
return permission_required('admin')(f)
方案2: 使用 Flask-Principal
from flask_principal import Principal, Permission, RoleNeed
principal = Principal()
admin_permission = Permission(RoleNeed('admin'))
editor_permission = Permission(RoleNeed('editor'))
# 在视图函数中使用
@app.route('/admin')
@admin_permission.require()
def admin():
return render_template('admin.html')
路由和视图示例
from flask import render_template, redirect, url_for, flash
from flask_login import login_user, logout_user, login_required
from .forms import LoginForm, RegistrationForm
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password(form.password.data):
login_user(user, remember=form.remember_me.data)
flash('登录成功', 'success')
return redirect(url_for('dashboard'))
flash('用户名或密码错误', 'danger')
return render_template('login.html', form=form)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('您已登出', 'info')
return redirect(url_for('login'))
@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html')
@app.route('/admin/users')
@login_required
@permission_required('user_management')
def user_management():
users = User.query.all()
return render_template('admin/users.html', users=users)
Bootstrap 后台模板结构
templates/
├── base.html # 基础模板
├── auth/
│ ├── login.html # 登录页面
│ └── register.html # 注册页面
├── admin/
│ ├── dashboard.html # 控制面板
│ ├── users.html # 用户管理
│ ├── roles.html # 角色管理
│ └── permissions.html # 权限管理
└── partials/
├── _header.html # 顶部导航
├── _sidebar.html # 侧边栏菜单
└── _footer.html # 页脚
权限动态菜单示例
在 _sidebar.html
中根据权限动态显示菜单:
<div class="sidebar">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('dashboard') }}">
<i class="fas fa-tachometer-alt"></i> 控制面板
</a>
</li>
{% if current_user.has_permission('user_management') %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('user_management') }}">
<i class="fas fa-users"></i> 用户管理
</a>
</li>
{% endif %}
{% if current_user.has_permission('role_management') %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('role_management') }}">
<i class="fas fa-user-tag"></i> 角色管理
</a>
</li>
{% endif %}
</ul>
</div>
初始化权限数据
可以创建一个命令来初始化基本角色和权限:
import click
from flask.cli import with_appcontext
@click.command('init-permissions')
@with_appcontext
def init_permissions():
"""初始化权限系统"""
# 创建基本权限
permissions = [
('dashboard_access', '访问控制面板', 'dashboard'),
('user_management', '用户管理', 'user_management'),
('role_management', '角色管理', 'role_management'),
('permission_management', '权限管理', 'permission_management'),
]
for name, desc, endpoint in permissions:
if not Permission.query.filter_by(name=name).first():
perm = Permission(name=name, description=desc, endpoint=endpoint)
db.session.add(perm)
# 创建基本角色
if not Role.query.filter_by(name='admin').first():
admin_role = Role(name='admin', description='超级管理员')
admin_role.permissions = Permission.query.all()
db.session.add(admin_role)
if not Role.query.filter_by(name='user').first():
user_role = Role(name='user', description='普通用户')
dashboard_perm = Permission.query.filter_by(name='dashboard_access').first()
if dashboard_perm:
user_role.permissions.append(dashboard_perm)
db.session.add(user_role)
db.session.commit()
print("权限系统初始化完成")
安全建议
- 使用 HTTPS
- 密码哈希存储 (如 bcrypt)
- CSRF 保护
- 限制登录尝试次数
- 敏感操作需要重新验证密码
- 定期审计权限分配
这个方案提供了完整的 Flask + Bootstrap 后台权限管理系统的基础架构,可以根据实际需求进行扩展和定制