Become a sponsor

RBAC权限
采用基于角色的访问控制(RBAC)模型,通过用户-角色-菜单三层关系实现细粒度的权限管理。权限控制贯穿前后端:后端通过 PermissionRequired 混入类校验(middleware/permission_middleware.py),前端通过 v-perm 指令控制按钮显隐。
用户(User) --N:N-- 角色(Role) --N:N-- 菜单(Menu)
|
type=0: 菜单(页面路由)
type=1: 节点(权限按钮)数据库表关系:
| 关联表 | 说明 |
|---|---|
django_user_role | 用户-角色关联表 |
django_role_menu | 角色-菜单关联表 |
django_menu | 菜单表(含权限节点) |
权限节点采用 sys:module:action 三段式命名:
sys:user:list 用户列表
sys:user:add 用户新增
sys:user:update 用户编辑
sys:user:delete 用户删除
sys:user:resetPwd 重置密码
sys:role:list 角色列表
sys:role:add 角色新增
sys:menu:list 菜单列表
sys:dept:list 部门列表
sys:level:list 职级列表
sys:position:list 岗位列表middleware/permission_middleware.py 中的 PermissionRequired 混入类用于基于类的视图权限校验:
from middleware.permission_middleware import PermissionRequired
@method_decorator(check_login, name="get")
class UserPageView(PermissionRequired, View):
permission_required = ("sys:user:page",)
def get(self, request):
result = services.get_user_page(request)
return result校验逻辑(完整实现):
# middleware/permission_middleware.py
from django.contrib.auth.mixins import PermissionRequiredMixin
class PermissionRequired(PermissionRequiredMixin):
def has_permission(self):
permissions = self.get_permission_required()
user_id = get_user_id(self.request)
# 超级管理员自动放行
if user_id and user_id != 1:
from application.menu import services
permission_list = services.get_user_permissions(user_id)
for permission in permissions:
if permission not in permission_list:
return False
return True
def handle_no_permission(self):
return R.failed("暂无操作权限", 401)管理员免检
用户ID为1的管理员账号(admin)自动跳过所有权限校验,拥有全部权限。
权限列表通过角色-菜单关联查询:
# application/menu/services.py
def get_user_permissions(user_id):
"""获取用户的权限节点列表"""
if user_id == 1:
# 超管拥有全部权限
menu_list = Menu.objects.filter(
type=1, is_delete=False
)
else:
# 通过 user -> role -> menu 关联查询
menu_list = Menu.objects.filter(
type=1,
is_delete=False,
status=0,
rolemenu__role__userrole__user_id=user_id,
rolemenu__role__is_delete=False,
).distinct()
return [item.permission for item in menu_list]前端使用自定义 v-perm 指令控制按钮显隐:
<!-- 只有拥有 sys:user:add 权限的用户才能看到此按钮 -->
<el-button v-perm="'sys:user:add'" type="primary">新增</el-button>
<!-- 多个权限,满足其一即可 -->
<el-button v-perm="['sys:user:update', 'sys:user:delete']">操作</el-button>前端路由守卫根据用户菜单权限动态生成路由,无权限的页面不会出现在导航菜单中。
RBAC 权限方案具备以下特点:
1. 三层模型:用户-角色-菜单,支持灵活的角色分配
2. 节点权限:sys:module:action 格式,细粒度控制每个操作
3. 前后端统一:后端 PermissionRequired + 前端 v-perm 指令
4. 管理员免检:userId=1 自动跳过权限校验
5. Django 原生:基于 Django PermissionRequiredMixin 扩展
6. 菜单路由:type=0 菜单生成前端路由,type=1 节点控制按钮权限