【后端】【Django DRF】从零实现RBAC 权限管理系统

Django DRF 实现 RBAC 权限管理系统

在 Web 应用中,权限管理 是一个核心功能,尤其是在多用户系统中,需要精细化控制不同用户的访问权限。本文介绍如何使用 Django + DRF 设计并实现 RBAC(基于角色的访问控制)系统 ,支持 目录、菜单、按钮权限


1. RBAC 体系结构设计

RBAC 主要包含以下核心概念:

  1. 用户(User):系统中的使用者。
  2. 角色(Role):用于分组用户,每个角色拥有不同的权限。
  3. 权限(Permission) :控制用户可以访问的资源,分为:
    • 目录(directory):仅用于分组,不可直接访问。
    • 菜单(menu):可点击,通常对应一个页面。
    • 按钮(button):更细粒度的操作权限,如"新增"、"编辑"按钮。

2. 数据模型设计

用户模型

继承 Django 的 AbstractUser,支持多角色:

python 复制代码
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    roles = models.ManyToManyField("Role", blank=True, related_name="users")

    def __str__(self):
        return self.username

角色模型

每个角色可以关联多个权限:

python 复制代码
class Role(models.Model):
    name = models.CharField(max_length=50, unique=True)
    permissions = models.ManyToManyField("Permission", blank=True, related_name="roles")

    def __str__(self):
        return self.name

权限模型

使用 type 字段区分 目录、菜单、按钮,并支持层级结构:

python 复制代码
class Permission(models.Model):
    TYPE_CHOICES = [
        ("directory", "目录"),
        ("menu", "菜单"),
        ("button", "按钮")
    ]
    
    name = models.CharField(max_length=100, unique=True)
    code = models.CharField(max_length=100, unique=True)  # 唯一标识
    type = models.CharField(max_length=10, choices=TYPE_CHOICES, default="menu")
    parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE, related_name="children")

    def __str__(self):
        return self.name

3. 数据序列化

使用 Django Rest Framework (DRF) 创建序列化器:

python 复制代码
from rest_framework import serializers

class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = "__all__"

class RoleSerializer(serializers.ModelSerializer):
    permissions = PermissionSerializer(many=True, read_only=True)

    class Meta:
        model = Role
        fields = "__all__"

class UserSerializer(serializers.ModelSerializer):
    roles = RoleSerializer(many=True, read_only=True)

    class Meta:
        model = User
        fields = "__all__"

4. 视图层

使用 viewsets 处理 API 逻辑,提供 增删改查

python 复制代码
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated

class PermissionViewSet(viewsets.ModelViewSet):
    queryset = Permission.objects.all()
    serializer_class = PermissionSerializer
    permission_classes = [IsAuthenticated]

class RoleViewSet(viewsets.ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    permission_classes = [IsAuthenticated]

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

5. API 路由配置

使用 DefaultRouter 自动生成路由:

python 复制代码
from rest_framework.routers import DefaultRouter
from django.urls import path, include

router = DefaultRouter()
router.register(r'permissions', PermissionViewSet)
router.register(r'roles', RoleViewSet)
router.register(r'users', UserViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

6. RBAC 角色权限管理示例

假设系统有以下需求:

  1. 管理员角色:可管理用户、分配角色,拥有所有权限。
  2. 普通用户角色:仅能访问特定菜单,不可管理用户。
  3. 按钮权限:仅某些角色可执行"删除用户"等操作。

创建权限

python 复制代码
Permission.objects.create(name="系统管理", code="sys_manage", type="directory")
Permission.objects.create(name="用户管理", code="user_manage", type="menu", parent_id=1)
Permission.objects.create(name="删除用户", code="btn_delete_user", type="button", parent_id=2)

创建角色并赋权

python 复制代码
admin_role = Role.objects.create(name="管理员")
user_role = Role.objects.create(name="普通用户")

admin_role.permissions.add(Permission.objects.get(code="sys_manage"))
user_role.permissions.add(Permission.objects.get(code="user_manage"))

创建用户并分配角色

python 复制代码
admin = User.objects.create_user(username="admin", password="admin123")
user = User.objects.create_user(username="user", password="user123")

admin.roles.add(admin_role)
user.roles.add(user_role)

7. 角色权限校验

用户登录后,前端可根据 菜单和按钮权限 动态渲染页面:

python 复制代码
def get_user_permissions(user):
    permissions = Permission.objects.filter(roles__users=user).values_list("code", flat=True)
    return list(permissions)

示例:

python 复制代码
get_user_permissions(admin)  
# 返回 ['sys_manage', 'user_manage', 'btn_delete_user']
python 复制代码
get_user_permissions(user)  
# 返回 ['user_manage']

前端可据此 控制菜单显示、按钮禁用,实现精细化权限管理。


8. 设计优势

灵活性 :支持 多级菜单、按钮权限控制 ,满足复杂权限需求。

可扩展性 :未来可新增 API 级别权限、数据权限 ,无需大改结构。

高效查询 :通过 ManyToManyForeignKey,高效检索用户权限。

前后端兼容 :前端可基于权限数据 动态渲染 UI,隐藏无权限功能。


9. 总结

本文基于 Django DRF 设计了 RBAC 角色权限管理系统,实现了:

  1. 目录、菜单、按钮 权限层级。
  2. 用户 - 角色 - 权限 关联设计。
  3. 序列化、视图、API 路由 处理。
  4. 角色分配、权限校验 方法。
  5. 前端动态权限控制 支持。

这种 基于 RBAC 的权限管理 适用于大多数 企业级管理系统 ,在 权限控制、扩展性、查询效率 方面均表现优越!🚀

相关推荐
Tyler先森12 分钟前
Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>
数据库·sql·oracle
KevinRay_1 小时前
从零开始学习SQL
数据库·学习·mysql
Json_181790144802 小时前
python采集淘宝拍立淘按图搜索API接口,json数据示例参考
服务器·前端·数据库
Albert Tan2 小时前
Oracle 10G DG 修复从库-磁盘空间爆满导致从库无法工作
数据库·oracle
好记忆不如烂笔头abc2 小时前
oracle-blob导出,在ob导入失败
大数据·数据库·python
私风翼2 小时前
SQL注入:基于GET和POST的报错注入详解
数据库·sql
神奇侠20242 小时前
快速入手-基于Django-rest-framework的serializers序列化器(二)
后端·python·django
好龙75753 小时前
MySQL 高级查询:JOIN、子查询、窗口函数
数据库·mysql
西木Qi3 小时前
Redis数据迁移同步
数据库·redis·缓存
暗恋 懒羊羊3 小时前
【MySQL】数据类型
数据库·mysql