博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rbac(基于角色权限控制)-------权限管理
阅读量:6648 次
发布时间:2019-06-25

本文共 8742 字,大约阅读时间需要 29 分钟。

权限管理
  创建一个rbac和app的应用,这个rbac主要是用来存放权限的,全称叫做基于角色权限控制
  一、先看配置文件合适不,给创建的rbac在配置文件里面设置一下
    找到INSTALLED_APPS=【'rbac'】
  二、设计表结构
    models中创建类:五个类,七张表
    角色表:
    用户表:
    权限表:

     组表:

     菜单表:

    角色表和权限表是多对多的关系(一个角色可以有多个权限,一个权限可以对应多个角色)

    用户表和角色表是多对多的关系(一个用户可以有多个角色,一个角色有多个用户)

    所以有会多生成两张关系表

    一个菜单下面有多个组

    一个组下面有多个菜单

    一个菜单下面有多个权限

from django.db import models# Create your models here.class Role(models.Model):    '''    角色表    '''    title = models.CharField(max_length=32,verbose_name="角色名")    permissions = models.ManyToManyField(to="Permission",verbose_name="具有的所有权限", blank=True)  # 建立用户表和角色表的多对多关系    def __str__(self):        return self.title    class Meta:        verbose_name_plural = "角色表"class Group(models.Model):    caption = models.CharField(max_length=32,verbose_name="组名称")    menu = models.ForeignKey(to="Menu",verbose_name="所属菜单",default=1,related_name="menu")class Menu(models.Model):    title = models.CharField(max_length=32)class Permission(models.Model):    '''    权限表    '''    title = models.CharField(max_length=32,verbose_name="标题")    url = models.CharField(max_length=64,verbose_name="带正则的URL")    # is_mune = models.BooleanField(verbose_name="是否是菜单",default=0)    menu_gp = models.ForeignKey(verbose_name="组内菜单",to="Permission",blank=True,null=True)  #自关联    #主页就可以设置为菜单,当点击菜单的时候才可以做具体的操作    codes = models.CharField(max_length=32,verbose_name="代码",default=1)    group = models.ForeignKey(to="Group",verbose_name="所属组",null=True)  #新添加的字段记得设置默认值    def __str__(self):        return self.title    class Meta:        '''中文显示'''        verbose_name_plural = "权限表"class UserInfo(models.Model):    '''    用户表    '''    username = models.CharField(max_length=32,verbose_name="用户名")    password = models.CharField(max_length=64,verbose_name="密码")    email = models.CharField(max_length=32,verbose_name="邮箱")    roles = models.ManyToManyField(to="Role",verbose_name="具有的所有角色",blank=True)  #建立用户和角色的多对多关系    def __str__(self):        return self.username    class Meta:        verbose_name_plural = "用户表"

 

  三、通过django admin录入权限数据
    - 先创建一个超级用户
    - 用户名 root
    - 密码 zhy123456
    - 在admin.py 中
      from rbac import models
      admin.site.register(models.Permission)
      admin.site.register(models.Role)
      admin.site.register(models.UserInfo)
      这样的话上去的是英文的,如果你想让中文显示就在类中加一个类
      class Meta:
      verbose_name_plural = "权限表"
      - 当你给关联字段录入数据的时候会有错误提示,那么在类中你的那个关联字段在加一个属性blank = True 可以为空
      permissions = models.ManyToManyField(to="Permission",verbose_name="具有的所有权限", blank=True)
  四、编写登录
    用户登录后:
      获取当前用户具有的所有角色
      获取当前用户具有的所有权限(并且去重)

      #获取当前的用户对象      user = models.UserInfo.objects.filter(username=name,password=password).first()      #获取当前用户的所有角色user.roles.all()      #获取当前用户的所有权限      permission_list = user.roles.all().values("permissions__title","permissions__url","permissions__is_mune").distinct()      print(permission_list)

      登录成功之后初始化---把所有的url都拿出来并且保存到session里

        1、可以建一个server的包,在里面建一个初始化的init_perssion.py文件
        2、定义函数

 

#!usr/bin/env python# -*- coding:utf-8 -*-from rbac import modelsfrom day7权限管理 import settingsdef init_permission(user,request):    #获取当前的用户对象    '''    获取所有权限中的url并放在session中    :param user:    :param request:    :return:    '''    #user.roles.all()获取当前用户的所有角色    #获取当前用户的所有权限    permission_list = user.roles.all().values(        "permissions__id",        "permissions__title",  #用户列表        "permissions__url",    #url        "permissions__menu_gp",  #组内菜单id,如果为null表示是菜单        "permissions__codes",        "permissions__group_id",        "permissions__group__menu__title",  #菜单名称        "permissions__group__menu__id"  #菜单id    ).distinct()    print("-----------------",permission_list)    #菜单相关    sub_permisson_list = []    for item in permission_list:        tpl = {            "id":item["permissions__id"],            "title":item["permissions__title"],            "url":item["permissions__url"],            "menu_group_id":item["permissions__group_id"],            "menu_id":item["permissions__group__menu__id"],            "menu_title":item["permissions__group__menu__title"]        }        sub_permisson_list.append(tpl)    request.session[settings.PERMISSION_MENU_KEY] = sub_permisson_list    # 1、去掉不是菜单的url    # 菜单操作    # menu_list = []    # for item in permission_list:    #     if not item["permissions__is_mune"]:  # 如果不是菜单就继续    #         continue    #     else:  # 否则是菜单的话就把菜单添加到列表里面    #         tpl = {
# "menu_id": item["permissions__group__menu__id"], # "menu_title": item["permissions__group__menu__title"], # "title": item["permissions__title"], # "url": item["permissions__url"], # "active": False # } # menu_list.append(tpl) # request.session[settings.PERMISSION_MENU_KEY] = menu_list #吧所有的菜单都放在session里面 # print("xcvxvxv", menu_list) # 权限相关 result = {} for item in permission_list: group_id = item["permissions__group_id"] url =item["permissions__url"] code = item["permissions__codes"] if group_id in result: #如果在说明url和code已经生成了 result[group_id]["codes"].append(code) result[group_id]["urls"].append(url) else: #如果不在就添加进去 result[group_id] ={ "codes":[code,], "urls":[url] } # print(result) #吧所有权限中的url字典放到session中 request.session[settings.PERMISSION_URL_DICT_KEY] = result # # 打印的结果如下 # result = {
# 1: {
# "codes": ["list", "add", "del", "edit"] # "urls": [ # "/userinfo/", # "/userinfo/add" , # "/userinfo/del(\d+)/ ", # "/userinfo/edit(\d+)/ ", # ] # }, # 2: {
# "codes": {"list", "add", "del", "edit"} # "urls": [ # "/order", # "/order/add" , # "/order/del(\d+)/ ", # "/order/edit(\d+)/ ", # ] # } # }

 

 

 

   五、中间件

      - 在setting里设置白名单(不用权限就可以访问)

#白名单VALID_URL = [    "/login/",    "/admin.*/",    "/index/"]# ==================rabc==============PERMISSION_URL_DICT_KEY="permissions_url_dict"PERMISSION_MENU_KEY = "menu_list"

 

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',    'rbac.middlewears.rbac.Middle',]

 

      - 获取当前的url请求
      - 获取session保存的权限信息

      - 循环url进行正则匹配,如果匹配成功就有权访问,不成功就无法访问

用中间件的时候记得要在settings里面配置一下:

 

#!usr/bin/env python# -*- coding:utf-8 -*-import refrom django.shortcuts import render,HttpResponse,redirectfrom django.conf import settingsclass MiddlewareMixin(object):    def __init__(self, get_response=None):        self.get_response = get_response        super(MiddlewareMixin, self).__init__()    def __call__(self, request):        response = None        if hasattr(self, 'process_request'):            response = self.process_request(request)        if not response:            response = self.get_response(request)        if hasattr(self, 'process_response'):            response = self.process_response(request, response)        return responseclass Middle(MiddlewareMixin):    def process_request(self,request):        #获取当前的url请求        current_url = request.path_info #拿到当前的路径        # print(request.path,current_url)        #获取Session中保存当前用户的权限,        # request.session.get("permissions_url_list")        # 如果当前的路径和session里面保存的url一样就break了,如果不一样就说明无权访问        for url in settings.VALID_URL:            # print(url,current_url)            if re.match(url,current_url):                return None    #如果url是表名单白名单里面的,就让直接走后面的        permission_dict = request.session.get(settings.PERMISSION_URL_DICT_KEY)        #在初始化的时候把url以字典的显示存在了session里面,现在获取的也就是一个字典了        # print("==========",permission_dict)        flag = False        for group_id,code_url in permission_dict.items():            for url in code_url["urls"]:                regax = "^{0}$".format(url)                # print(regax,current_url)                if re.match(regax,current_url):                    #match只要是..开头的都能匹配到,多以的加个^和$符                    request.permission_code_list=code_url["codes"]                    flag = True                    break            if flag:  #跳出外层循环                break        if not flag:            return HttpResponse("无权访问")    def process_response(self,request,response):        return response

 

转载地址:http://dgevo.baihongyu.com/

你可能感兴趣的文章
Function 与 Classes 组件的区别在哪?
查看>>
[杭州/新加坡] imToken 招聘前端工程师
查看>>
Flutter视图基础简介--Widget、Element、RenderObject
查看>>
SpringBoot中json转换问题(客户端交互)
查看>>
isKindOfClass和isMemberOfClass的区别
查看>>
JS检测对象中是否存在某个属性
查看>>
简析社群运营的玩法
查看>>
模拟服务器返回数据|掘金技术征文
查看>>
用百度云的时序数据库给京价保加了个价格走势图功能
查看>>
开源PaaS Rainbond v3.7.0-rc1版本更新,系统生产稳定性大幅提升
查看>>
使用脚手架搭建VUE项目
查看>>
iOS底层(二)-函数本质
查看>>
Go基础知识-04 时间和日期类型(持续更新)
查看>>
程序员的基本常识——学习篇
查看>>
spring cloud微服务分布式云架构--服务注册(consul)
查看>>
03 基于umi搭建React快速开发框架(列表封装)
查看>>
JavaScript数组去重方法总结
查看>>
什么都不必说--springboot集成rabbitmq
查看>>
java中的static关键字解析
查看>>
Ubuntu Nginx php 安装与环境配置
查看>>