【django后端分离】rbac组件(文件源代码+使用)
PythonNew_Mr.Wang 人气:01:用户,角色,权限,菜单表设计
from django.db import models # 用户菜单 class UserMenu(models.Model): title = models.CharField(max_length=32, verbose_name='菜单') icon = models.CharField(max_length=32, verbose_name='图标', null=True, blank=True) def __str__(self): return self.title class Meta: verbose_name = "菜单" verbose_name_plural = verbose_name # 用户信息表 class UserInfo(models.Model): username = models.CharField(unique=True, max_length=32, verbose_name="用户名") password = models.CharField(max_length=64) roles = models.ManyToManyField(to='Role', verbose_name='用户所拥有的角色', blank=True) is_staff = models.BooleanField(default=True) # admin配置 def __str__(self): return self.username class Meta: verbose_name = "用户信息" verbose_name_plural = verbose_name # 角色表 class Role(models.Model): name = models.CharField(max_length=32, verbose_name='角色名称') permissions = models.ManyToManyField(to='Permission', verbose_name='角色所拥有的权限', blank=True) def __str__(self): return self.name # 权限表 class Permission(models.Model): title = models.CharField(max_length=32, verbose_name='权限名') url = models.CharField(max_length=32, verbose_name='权限') menu = models.ForeignKey("UserMenu", on_delete=models.CASCADE, null=True) name = models.CharField(max_length=32, verbose_name='url别名', default="") class Meta: verbose_name_plural = '权限表' verbose_name = '权限表' def __str__(self): return self.title
2:rbac.py
from dal.models import Role def initial_sesson(user,request): """ 功能:将当前登录人的所有权限录入session中 :param user: 当前登录人 """ # 查询当前登录人的所有权限列表 # 查看当前登录人的所有角色 # ret=Role.objects.filter(user=user) permissions = Role.objects.filter(userinfo__username=user).values("permissions__url", "permissions__title", "permissions__name", "permissions__menu__title", "permissions__menu__icon", "permissions__menu__pk").distinct() # print("permissions",permissions) permission_list = [] permission_names = [] permission_menu_dict ={} for item in permissions: # 构建权限列表 permission_list.append(item["permissions__url"]) permission_names.append(item["permissions__name"]) # 菜单权限 menu_pk=item["permissions__menu__pk"] if menu_pk: if menu_pk not in permission_menu_dict: permission_menu_dict[menu_pk]={ "menu_title":item["permissions__menu__title"], "menu_icon":item["permissions__menu__icon"], "children":[ { "title":item["permissions__title"], "url":item["permissions__url"], } ], } else: permission_menu_dict[menu_pk]["children"].append({ "title": item["permissions__title"], "url": item["permissions__url"], }) # print("permission_menu_dict",permission_menu_dict) # 将当前登录人的权限列表注入session中 request.session["permission_list"] = permission_list request.session["permission_names"] = permission_names # 将当前登录人的菜单权限字典注入session中 request.session["permission_menu_dict"] = permission_menu_dict return permission_menu_dict
3:middlewares.py中间件验证权限文件
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse,redirect import re from django.http import JsonResponse class PermissionMiddleWare(MiddlewareMixin): def process_request(self,request): print("permission_list的值是:",request.session.get("permission_list")) current_path = request.path message = {} # 设置白名单放行 for reg in ["/user/login","/admin/*"]: ret=re.search(reg,current_path) if ret: return None # /customers/edit/1 try: # 校验权限 permission_list=request.session.get("permission_list") for reg in permission_list: reg="^%s$"%reg ret=re.search(reg,current_path) if ret: return None message['message'] = "提示:无访问权限" message['code'] = 404 return JsonResponse(message) except Exception as e: print(e) message['message'] = "提示:无访问权限" message['code'] = 404 return JsonResponse(message)
4:中间件配置与登录视图的配置
# settings.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'user.rbac_utils.middlewares.PermissionMiddleWare', # 配置中间件 ] # 登录函数的配置: 这里只是写关于权限配置的部分函数,其余的token需求自己写 # 保存登录用户状态信息 request.session["user_id"] = user_obj.pk # 录入权限session permission_menu_dict = initial_sesson(username, request) # 设置返回给前端的值 csrf = {} csrf['permission_menu_dict'] = permission_menu_dict csrf['token'] = token return JsonResponse(csrf)
加载全部内容