本文目录导读:

在Python中分配用户权限,通常有几种常见的实现方案,取决于你的应用场景,我为你整理了从简单到复杂的几种典型案例:
基于角色的权限控制(RBAC) - 最常用
这是最常见的权限管理方式,适用于Web应用、后台管理系统等。
简单实现示例:
from enum import Enum
from functools import wraps
# 定义权限类型
class Permission(Enum):
CREATE_USER = "create_user"
DELETE_USER = "delete_user"
VIEW_REPORT = "view_report"
EDIT_SETTINGS = "edit_settings"
# 定义角色及其权限
ROLES = {
"admin": [Permission.CREATE_USER, Permission.DELETE_USER,
Permission.VIEW_REPORT, Permission.EDIT_SETTINGS],
"editor": [Permission.CREATE_USER, Permission.VIEW_REPORT],
"viewer": [Permission.VIEW_REPORT]
}
class User:
def __init__(self, username, role):
self.username = username
self.role = role
self.permissions = ROLES.get(role, [])
def has_permission(self, permission):
return permission in self.permissions
# 权限装饰器
def require_permission(permission):
def decorator(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.has_permission(permission):
raise PermissionError(f"用户{user.username}没有权限执行此操作")
return func(user, *args, **kwargs)
return wrapper
return decorator
# 使用示例
@require_permission(Permission.DELETE_USER)
def delete_user(admin, target_user_id):
print(f"用户{admin.username}删除了用户{target_user_id}")
# 测试
admin = User("张三", "admin")
editor = User("李四", "editor")
try:
delete_user(admin, 1) # 成功
delete_user(editor, 2) # 抛出权限错误
except PermissionError as e:
print(f"错误: {e}")
基于位运算的权限控制 - 高性能
适合需要高性能、且权限数量不超过64个的场景(如游戏、高性能服务)。
class Permission:
# 使用2的幂定义权限
READ = 1 << 0 # 1
WRITE = 1 << 1 # 2
DELETE = 1 << 2 # 4
ADMIN = 1 << 3 # 8
class UserPermissions:
def __init__(self, permissions=0):
self.permissions = permissions
def add_permission(self, perm):
self.permissions |= perm
def remove_permission(self, perm):
self.permissions &= ~perm
def has_permission(self, perm):
return (self.permissions & perm) == perm
def has_any_permission(self, *perms):
for perm in perms:
if self.has_permission(perm):
return True
return False
# 使用示例
user_perms = UserPermissions()
user_perms.add_permission(Permission.READ | Permission.WRITE)
print(f"是否有读权限: {user_perms.has_permission(Permission.READ)}") # True
print(f"是否有删除权限: {user_perms.has_permission(Permission.DELETE)}") # False
print(f"是否有读写权限: {user_perms.has_permission(Permission.READ | Permission.WRITE)}") # True
# 权限组合直接存储到数据库 (仅需一个整数字段)
db_storage = user_perms.permissions # 存储为整数: 3
使用第三方库 - Django的权限系统
如果你在使用Django框架,推荐使用其内置权限系统:
# Django 模型示例
from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Article(models.Model):= models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
permissions = [
("publish_article", "可以发布文章"),
("archive_article", "可以归档文章"),
]
# 分配权限
def assign_permissions(user):
# 获取特定权限
content_type = ContentType.objects.get_for_model(Article)
permission = Permission.objects.get(
codename='publish_article',
content_type=content_type,
)
# 为用户分配权限
user.user_permissions.add(permission)
# 或者使用组分配
from django.contrib.auth.models import Group
editor_group = Group.objects.get(name='编辑')
editor_group.permissions.add(permission)
user.groups.add(editor_group)
# 检查权限
def check_permission(user):
if user.has_perm('myapp.publish_article'):
# 有权限
pass
# 在模板中使用
# {% if perms.myapp.publish_article %}
# 有权限
# {% endif %}
ACL(访问控制列表) - 细粒度控制
适合需要精确控制每个用户对每个资源的访问:
from dataclasses import dataclass
from typing import Dict, Set
@dataclass
class Resource:
id: str
type: str
class AccessControlList:
def __init__(self):
# 格式: {用户ID: {资源ID: {权限集合}}}
self.acl: Dict[str, Dict[str, Set[str]]] = {}
def grant_permission(self, user_id: str, resource: Resource, permission: str):
if user_id not in self.acl:
self.acl[user_id] = {}
if resource.id not in self.acl[user_id]:
self.acl[user_id][resource.id] = set()
self.acl[user_id][resource.id].add(permission)
def revoke_permission(self, user_id: str, resource: Resource, permission: str):
if user_id in self.acl and resource.id in self.acl[user_id]:
self.acl[user_id][resource.id].discard(permission)
def check_permission(self, user_id: str, resource: Resource, permission: str) -> bool:
if user_id in self.acl:
user_perms = self.acl[user_id]
if resource.id in user_perms:
return permission in user_perms[resource.id]
return False
# 使用示例
acl = AccessControlList()
doc = Resource("doc-001", "document")
# 授予权限
acl.grant_permission("user1", doc, "read")
acl.grant_permission("user1", doc, "write")
# 检查权限
print(acl.check_permission("user1", doc, "read")) # True
print(acl.check_permission("user1", doc, "delete")) # False
print(acl.check_permission("user2", doc, "read")) # False
实际案例:Web API权限控制
结合Flask/FastAPI的完整示例:
from flask import Flask, request, jsonify, g
from functools import wraps
import jwt
from datetime import datetime, timedelta
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
# 权限配置
PERMISSIONS = {
'read_users': '查看用户列表',
'create_users': '创建用户',
'delete_users': '删除用户',
'view_reports': '查看报表',
}
ROLES = {
'admin': ['read_users', 'create_users', 'delete_users', 'view_reports'],
'manager': ['read_users', 'view_reports'],
'operator': ['read_users', 'create_users'],
}
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'error': '缺少token'}), 401
try:
# 解析JWT token
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
g.user = payload
except:
return jsonify({'error': '无效的token'}), 401
return f(*args, **kwargs)
return decorated_function
def require_permission(permission):
def decorator(f):
@wraps(f)
@login_required
def decorated_function(*args, **kwargs):
user_role = g.user.get('role')
user_permissions = ROLES.get(user_role, [])
if permission not in user_permissions:
return jsonify({'error': '权限不足'}), 403
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/api/users', methods=['GET'])
@require_permission('read_users')
def get_users():
return jsonify({'users': ['user1', 'user2']})
@app.route('/api/users', methods=['POST'])
@require_permission('create_users')
def create_user():
return jsonify({'message': '用户创建成功'})
# 登录API - 获取token
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
# 验证用户凭证(简化示例)
if username == 'admin' and password == 'admin123':
token = jwt.encode({
'username': username,
'role': 'admin',
'exp': datetime.utcnow() + timedelta(hours=24)
}, app.config['SECRET_KEY'])
return jsonify({'token': token})
return jsonify({'error': '用户名或密码错误'}), 401
if __name__ == '__main__':
app.run(debug=True)
推荐的最佳实践
-
存储方案:
- 小项目:使用
SQLite+ 简单的角色表 - 大项目:使用
PostgreSQL+ 完整的RBAC表结构
- 小项目:使用
-
数据库表结构示例:
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50) UNIQUE,
role_id INT
);
-- 角色表
CREATE TABLE roles (
id INT PRIMARY KEY,
name VARCHAR(50) UNIQUE,
description TEXT
);
-- 权限表
CREATE TABLE permissions (
id INT PRIMARY KEY,
name VARCHAR(50) UNIQUE,
description TEXT
);
-- 角色-权限关联表
CREATE TABLE role_permissions (
role_id INT REFERENCES roles(id),
permission_id INT REFERENCES permissions(id),
PRIMARY KEY (role_id, permission_id)
);
-- 用户-额外权限表(可选,用于特殊情况)
CREATE TABLE user_permissions (
user_id INT REFERENCES users(id),
permission_id INT REFERENCES permissions(id),
PRIMARY KEY (user_id, permission_id)
);
- 权限设计原则:
- 最小权限原则:只给用户必要的最小权限
- 权限分离:不要把所有权限给一个人
- 定期审查:定期检查权限分配是否合理
选择哪种方案取决于你的具体需求:
- 简单应用:使用角色控制足够了
- 复杂业务:需要考虑ACL或ABAC(基于属性的访问控制)
- Web框架:尽量使用框架内置的权限系统
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播