django的权限角色管理(RBAC)
什么是 RBAC
RBAC(Role-Based Access Control,基于角色的访问控制)是一种常见的权限管理模型,核心思想是将权限赋给“角色”,再把用户赋给角色,从而实现灵活且易维护的权限控制。
RBAC 的基本概念
| 概念 | 说明 |
|---|---|
| 用户 (User) | 使用系统的个体,如管理员、普通用户等 |
| 角色 (Role) | 权限的集合,比如“管理员”、“编辑者”、“访客”等 |
| 权限 (Permission / Scope) | 对某个操作或资源的授权,例如 user:read, user:write |
| 资源 (Resource) | 系统中的功能、数据或操作对象(可选扩展) |
核心机制
RBAC 的核心是 3 个关系:
-
用户 ↔ 角色:一个用户可以有多个角色
-
角色 ↔ 权限:一个角色可以有多个权限
-
用户 ↔ 权限:用户通过角色间接获得权限
RBAC 的优点
-
高复用:权限统一配置在角色中,避免重复赋权
-
易管理:改角色即可调整所有用户权限
-
易扩展:适用于大中型系统、支持多层级权限体系
-
可审计:权限来源清晰,可跟踪审计
常见变体(RBAC Plus)
| 模型 | 描述 |
|---|---|
| RBAC0 | 基础版:用户-角色-权限 |
| RBAC1 | 支持角色继承(如“超级管理员”继承“管理员”权限) |
| RBAC2 | 加入约束条件,比如时间、生效范围、地域等 |
| RBAC3 | 综合:角色继承 + 权限约束 + 会话支持等 |
| RBAC + ABAC | 将 RBAC 与属性权限(如资源拥有者、IP、部门等)结合 |
在 Django 中,User、Group 和 Permission 是权限系统的核心组件。下面通过代码示例演示它们的 CRUD(创建、读取、更新、删除) 操作:
一、User 模型 CRUD
from django.contrib.auth.models import User
# 创建用户
user = User.objects.create_user(
username='alice',
email='alice@example.com',
password='securepassword'
)
# 读取用户
user = User.objects.get(username='alice') # 获取单个用户
users = User.objects.all() # 获取所有用户
active_users = User.objects.filter(is_active=True) # 过滤查询
# 更新用户
user.email = 'new_email@example.com'
user.is_staff = True
user.save()
# 删除用户
user.delete()
二、Group 模型 CRUD
from django.contrib.auth.models import Group, Permission
# 创建组
group = Group.objects.create(name='编辑组')
# 读取组
group = Group.objects.get(name='编辑组')
groups = Group.objects.all()
# 更新组
group.name = '高级编辑组'
group.save()
# 删除组
group.delete()
# 为组分配权限
permission = Permission.objects.get(codename='add_post')
group.permissions.add(permission) # 添加单个权限
group.permissions.remove(permission) # 移除单个权限
group.permissions.clear() # 清空所有权限
三、Permission 模型 CRUD
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from myapp.models import Article # 假设 Article 是你的模型
# 创建自定义权限(通常通过模型的 Meta 类定义)
content_type = ContentType.objects.get_for_model(Article)
permission = Permission.objects.create(
codename='can_publish',
name='Can publish articles',
content_type=content_type
)
# 读取权限
permission = Permission.objects.get(codename='can_publish')
permissions = Permission.objects.filter(content_type=content_type)
# 更新权限
permission.name = 'Can publish and unpublish articles'
permission.save()
# 删除权限
permission.delete()
四、关联操作
1. 用户与组的关联
user = User.objects.get(username='alice')
group = Group.objects.get(name='编辑组')
user.groups.add(group) # 用户加入组
user.groups.remove(group) # 用户退出组
user.groups.clear() # 用户退出所有组
user.groups.set([group]) # 用户只属于指定组
2. 用户与权限的直接关联
permission = Permission.objects.get(codename='add_post')
user.user_permissions.add(permission) # 直接为用户分配权限
user.user_permissions.remove(permission) # 移除用户权限
user.user_permissions.clear() # 清空用户所有权限
五、查询示例
1. 获取用户的所有权限
user = User.objects.get(username='alice')
all_permissions = user.get_all_permissions() # 返回权限字符串集合
2. 检查用户是否有某个权限
if user.has_perm('myapp.add_article'):
print("用户有权限")
else:
print("用户无权限")
3. 获取组的所有成员
group = Group.objects.get(name='编辑组')
users_in_group = group.user_set.all()
六、特殊操作
1. 创建超级用户
# 方法 1:命令行创建
python manage.py createsuperuser
# 方法 2:代码创建
User.objects.create_superuser(
username='admin',
email='admin@example.com',
password='adminpassword'
)
2. 修改用户密码
user = User.objects.get(username='alice')
user.set_password('new_secure_password')
user.save()
七 模型关系图




# 权限与角色(组)相关联,用户通过称为适当角色(组)的成员而得到这些角色(组)的权限
# 极大的简化了权限的管理(相互依赖)
# Django的Auth组件(app)采用的认证规则就是RBAC
1 User表 :存用户信息
2 Permission表 :存权限
3 Role表 :存角色(组)4 Group_Role中间表 :权限赋予角色(多对多)
5 User_Group中间表 :角色赋予用户(多对多)
6 User_Permission中间表 :权限临时赋予角色(多对多)
'''
ps:
1 Django后台管理admin自带RBAC
'''
八 手动实现一下关联关系
from django import models
from datetime import datetime, timezone
class Permission(models.Model):
"""
权限表
"""
name = models.CharField(max_length=255)
codename = models.CharField(max_length=100)
class Group(models.Model):
"""
分组表
"""
name = models.CharField(max_length=150)
permissions = models.ManyToManyField(
Permission,
through='GroupPermission', # 指定模型
through_fields=('group', 'permission'), # 指定字段
blank=True
)
class User(models.Model):
"""
用户表
"""
username = models.CharField(max_length=150)
password = models.CharField(max_length=128)
email = models.EmailField(max_length=254)
fist_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(null=True, default=timezone.now)
groups = models.ManyToManyField(
Group,
through='UserGroup', # 指定模型
through_fields=('user', 'group'), # 指定字段
blank=True
)
user_permissions = models.ManyToManyField(
Permission,
through='UserPermission', # 指定模型
through_fields=('user', 'permission'), # 指定字段
blank=True
)
class UserGroup(models.Model):
"""
用户和分组关系表
"""
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
group_id = models.ForeignKey(Group, on_delete=models.CASCADE)
class UserPermission(models.Model):
"""
用户和权限关系表
"""
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
permission_id = models.ForeignKey(Permission, on_delete=models.CASCADE)
九 自动关联关系
class Permission(models.Model):
"""
权限表
"""
name = models.CharField(max_length=255)
codename = models.CharField(max_length=100)
class Group(models.Model):
"""
分组表
"""
name = models.CharField(max_length=150)
permissions = models.ManyToManyField(Permission, blank=True)
class User(models.Model):
"""
用户表
"""
username = models.CharField(max_length=150)
password = models.CharField(max_length=128)
email = models.EmailField(max_length=254)
fist_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(null=True, default=timezone.now)
groups = models.ManyToManyField(Group, blank=True)
user_permissions = models.ManyToManyField(Permission, blank=True)
更多推荐
所有评论(0)