【django后端分离】rbac组件(文件源代码+使用)

1:用户,角色,权限,菜单表设计

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
models

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
View Code

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)
View Code

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)

你可能感兴趣的:(【django后端分离】rbac组件(文件源代码+使用))