权限管理的三级菜单的流程及使用流程

权限管理的三级菜单的流程

权限控制

  • url代表了权限
  • 表结构(6张表,ORM创建4个类,两个many2many会自动再生成两张表)
    用户表    用户名    密码    多对多 roles(角色)角色表    标题 title    多对多 permission(权限)权限表    标题 title    权限 url    URL别名 name    - 设置唯一(方便为了将权限粒度控制到按钮级别)    外键 menu(菜单)    外键 permission(self自己)菜单表    标题 title    图标 icon    权重 weight用户和角色关系表角色和权限的关系表
    from django.db import models??class Menu(models.Model):    """    一级菜单    """    title = models.CharField(max_length=32, verbose_name=‘标题‘, unique=True)  # 一级菜单的名字    icon = models.CharField(max_length=32, verbose_name=‘图标‘, null=True, blank=True)    weight = models.IntegerField(verbose_name=‘权重‘, default=1)?    class Meta:        verbose_name_plural = ‘菜单表‘        verbose_name = ‘菜单表‘?    def __str__(self):        return self.title??class Permission(models.Model):    """    权限表    有关联Menu的二级菜单    没有关联Menu的不是二级菜单,是不可以做菜单的权限    """    title = models.CharField(max_length=32, verbose_name=‘标题‘)    url = models.CharField(max_length=32, verbose_name=‘权限‘)    menu = models.ForeignKey(‘Menu‘, null=True, blank=True, verbose_name=‘菜单‘)    # 该权限关联的其他权限是否也是在当前url上展示    parent = models.ForeignKey(to=‘Permission‘, null=True, blank=True, verbose_name=‘父权限‘)?    name = models.CharField(max_length=32, null=True, blank=True, unique=True, verbose_name=‘权限的别名‘)?    class Meta:        verbose_name_plural = ‘权限表‘        verbose_name = ‘权限表‘?    def __str__(self):        return self.title??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 User(models.Model):    """    用户表    """    name = models.CharField(max_length=32, verbose_name=‘用户名‘)    password = models.CharField(max_length=32, verbose_name=‘密码‘)    roles = models.ManyToManyField(to=‘Role‘, verbose_name=‘用户所拥有的角色‘, blank=True)?    def __str__(self):        return self.name?
  • 流程梳理
    - 当一个url回车发出这个请求后,给到server端先判断这个请求url是不是有访问的权限  这个时候我们设置了白名单(在中间件这里(因为一开始就要判断身份)),如果是白名单  谁都可以访问  eg:    PERMISSION_SESSION_KEY = ‘permissions‘    MENU_SESSION_KEY = ‘menus‘    WHITE_URL_LIST = [        r‘^/login/$‘,        r‘^/logout/$‘,        r‘^/reg/$‘,        r‘^/admin/.*‘,    ]
    - 这时用户登录,如果登录成功  不同的用户对应不同的权限,也就是可以访问不同的url
    - 登录成功,(权限信息的初始化)  我们该做的就是拿到这个用户对应的权限信息 - ORM(用户信息-角色-权限-菜单)  # user = models.User.objects.filter(name=username, password=pwd).first()  permission_query = user.roles.filter(permissions__url__isnull=False).values(        ‘permissions__url‘,  # 权限url        ‘permissions__title‘,  # 权限的标题        ‘permissions__id‘,  # 权限的id        ‘permissions__name‘,  # 权限的别名        ‘permissions__parent_id‘,  # 此权限对应的父权限的id        ‘permissions__parent__name‘,  # 次权限对应的父权限的别名        ‘permissions__menu_id‘,  # 此权限对应的菜单id        ‘permissions__menu__title‘,  # 此权限对应的菜单标题        ‘permissions__menu__icon‘,  # 此权限对应的菜单的图标        ‘permissions__menu__weight‘,  # 表单排序用的    ).distinct()  数据结构(字典)  permission_dict来存储此权限信息  menu_dict来存储菜单信息  permission_dict = {      ‘URL的别名‘:{‘url‘,‘title‘,‘id‘,‘pid‘,‘pname‘ }  }  menu_list = {      ‘菜单ID‘:{                    ‘title‘: 一级菜单的标题,                    ‘icon‘: 一级菜单的图标,                    ‘weight‘: 权重,                    ‘children‘: [                            {‘url‘,‘title‘,‘id‘,}                        ]                    }  }
    权限信息存的就是:    当前这个权限的是谁,他的id多少,他的标题是什么,他的父权限是谁(id),他的父权限的别名是什么菜单信息存的就是:    这个权限(url)对应的菜单的标题是什么,菜单的图标是什么,权重是多少,他对应的二级菜单是哪些    二级菜单(children)也就是,对应的权限信息    这里面存的也就是他的权限信息(他的title,url,id,parent_id)将所有的权限遍历一遍后,将这些信息存入session中    为什么存入session,是因为session可以配置(放入缓存,访问次数比较多,所有存到缓存比较好)
  # 遍历此用户对应的权限信息  for item in permission_query:        # 首先是权限信息,以权限的别名为键          permission_dict[item[‘permissions__name‘]] = ({              ‘url‘: item[‘permissions__url‘],              ‘id‘: item[‘permissions__id‘],              ‘parent_id‘: item[‘permissions__parent_id‘],              ‘parent_name‘: item[‘permissions__parent__name‘],              ‘title‘: item[‘permissions__title‘],          })          menu_id = item.get(‘permissions__menu_id‘)          if not menu_id:              continue          if menu_id not in menu_dict:              menu_dict[menu_id] = {                  ‘title‘: item[‘permissions__menu__title‘],                  ‘icon‘: item[‘permissions__menu__icon‘],                  ‘weight‘: item[‘permissions__menu__weight‘],                  ‘children‘: [                      {                          ‘title‘: item[‘permissions__title‘],                          ‘url‘: item[‘permissions__url‘],                          ‘id‘: item[‘permissions__id‘],                          ‘parent_id‘: item[‘permissions__parent_id‘],                      }                  ]              }          else:              menu_dict[menu_id][‘children‘].append(                  {                      ‘title‘: item[‘permissions__title‘],                      ‘url‘: item[‘permissions__url‘],                      ‘id‘: item[‘permissions__id‘],                      ‘parent_id‘: item[‘permissions__parent_id‘],                  })
  - 登录成功后,信息存入session后,这时给服务器发送一个请求,这时就会走中间件进行权限的校验    - 走中间件process_request(self, request):    - 先获取这个请求的url   request.path_info        刚开始也先判断白名单, 白名单不符合从session中获取这个用户存的权限信息        permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)    - 导航栏可以存这里  - 写了一个inclution_tag来处理        request.breadcrumd_list = [              {"title": ‘首页‘, ‘url‘: ‘#‘},          ]          @register.inclusion_tag(‘rbac/breadcrumbs.html‘)        def breadcrumb(request):            return {"breadcrumd_list": request.breadcrumd_list}    - 遍历这个权限信息        可以通过正则匹配,匹配他是不是该用户的权限        如果匹配成功看他是否由parent_id有是子权限没有是父权限

if parent_id:            # 表示当前权限是子权限,让父权限是展开              request.current_menu_id = parent_id              request.breadcrumd_list.extend([                {                  "title": permission_dict[parent_name][‘title‘],                    ‘url‘: permission_dict[parent_name][‘url‘]                   },                     {"title": item[‘title‘], ‘url‘: item[‘url‘]},                   ])           else:            # 表示当前权限是父权限,要展开的二级菜单              request.current_menu_id = id              # 添加面包屑导航              request.breadcrumd_list.append({                "title": item[‘title‘],                 ‘url‘: item[‘url‘]              })            - request.current_menu_id            这个就是用来展示菜单和展示该权限的子权限为了选中同一个二级菜单的时候用的            -写一个includtion_tag            -                @register.inclusion_tag(‘rbac/menu.html‘)                  def menu(request):                      menu_list = request.session.get(settings.MENU_SESSION_KEY)                      order_dict = OrderedDict()                      for key in sorted(menu_list, key=lambda x: menu_list[x][‘weight‘], reverse=True):                          order_dict[key] = menu_list[key]                          item = order_dict[key]                          item[‘class‘] = ‘hide‘                            for i in item[‘children‘]:                                if i[‘id‘] == request.current_menu_id:                                  i[‘class‘] = ‘active‘                                  item[‘class‘] = ‘‘                      return {"menu_list": order_dict}
  from django.utils.deprecation import MiddlewareMixin  from django.conf import settings  from django.shortcuts import HttpResponse  import re      class PermissionMiddleware(MiddlewareMixin):      def process_request(self, request):          # 对权限进行校验          # 1. 当前访问的URL          current_url = request.path_info            # 白名单的判断          for i in settings.WHITE_URL_LIST:              if re.match(i, current_url):                  return            # 2. 获取当前用户的所有权限信息            permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)            request.breadcrumd_list = [              {"title": ‘首页‘, ‘url‘: ‘#‘},          ]            # 3. 权限的校验          print(current_url)            for item in permission_dict.values():              print(permission_dict)              url = item[‘url‘]              if re.match("^{}$".format(url), current_url):                  parent_id = item[‘parent_id‘]                  id = item[‘id‘]                  parent_name = item[‘parent_name‘]                  if parent_id:                      # 表示当前权限是子权限,让父权限是展开                      request.current_menu_id = parent_id                      request.breadcrumd_list.extend([                          {"title": permission_dict[parent_name][‘title‘],                           ‘url‘: permission_dict[parent_name][‘url‘]},                          {"title": item[‘title‘], ‘url‘: item[‘url‘]},                      ])                  else:                      # 表示当前权限是父权限,要展开的二级菜单                      request.current_menu_id = id                      # 添加面包屑导航                      request.breadcrumd_list.append({"title": item[‘title‘], ‘url‘: item[‘url‘]})                  return          else:              return HttpResponse(‘没有权限‘)  
  - 权限力度控制到按钮级别    一个filter    一个url的反向解析    @register.filter    def has_permission(request, permission):        # session中存的就是权限的别名,别名就是反向解析的那个字符串        if permission in request.session.get(settings.PERMISSION_SESSION_KEY):            return True
  {% if request|has_permission:‘web:customer_edit‘ or request|has_permission:‘web:customer_del‘ %}  <td>  {% if request|has_permission:‘web:customer_edit‘ %}  <a style="color: #333333;" href="{% url ‘web:customer_edit‘ row.id %}">  <i class="fa fa-edit" aria-hidden="true"></i></a>  {% endif %}  {% if request|has_permission:‘web:customer_del‘ %}  <a style="color: #d9534f;" href="{% url ‘web:customer_del‘ row.id  %}"><i class="fa fa-trash-o"></i></a>  {% endif %}

菜单和权限的展示在一个页面

# 菜单和权限的展示# 点击每一个菜单出现对应的权限信息def menu_list(request):    all_menu = models.Menu.objects.all()    # 拿到菜单对应的菜单id    mid = request.GET.get(‘mid‘)    # 如果拿到菜单id代表着有子权限    if mid:        # 从子权限出发 拿到 父权限对应的菜单id对应的权限  或者  菜单对应的权限(也就是二级菜单) 因为自己关联自己(从父亲和儿子两方面出发)        permission_query = models.Permission.objects.filter(Q(menu_id=mid) | Q(parent__menu_id=mid))    # 如果没有菜单id则输出所有的权限信息    else:        permission_query = models.Permission.objects.all()    # 拿到查询出的权限对应的信息    all_permission = permission_query.values(‘id‘, ‘url‘, ‘title‘, ‘name‘, ‘menu_id‘, ‘parent_id‘, ‘menu__title‘)    all_permission_dict = {}    for item in all_permission:        menu_id = item.get(‘menu_id‘)        # 找到有菜单id的权限,将其存入字典,键为权限的id        if menu_id:            all_permission_dict[item[‘id‘]] = item            # 可以改都是引用            # 得到所有有菜单的权限后,将每一个权限都设置一个children键值对,用来存储子权限信息            item[‘children‘] = []    for item in all_permission:        pid = item.get(‘parent_id‘)        # 如果有父id代表的是子权限        if pid:            # 如果是子权限,就将子权限的信息存入多上一步做的处理(有菜单的父权限)children中            all_permission_dict[pid][‘children‘].append(item)    return render(request, ‘rbac/menu_list.html‘, {        "mid": mid,        "all_menu": all_menu,        "all_permission_dict": all_permission_dict,    })

权限系统的应用

  • 拷贝rbac App到新项目中
  • 注册APP 以及配置信息
    #  ###### 权限相关的配置 ######PERMISSION_SESSION_KEY = ‘permissions‘MENU_SESSION_KEY = ‘menus‘WHITE_URL_LIST = [    r‘^/login/$‘,    r‘^/logout/$‘,    r‘^/reg/$‘,    r‘^/admin/.*‘,]
  • 数据库迁移命令
    • 删除rbac所有的迁移文件
    • 执行两条命令
  • 路由相关
    • url(r‘rbac/‘,include(‘rbac.urls‘,namespace=‘rbac‘))
    • 给所有的URL起名字
  • layout 模板注意
    • block css js content
  • 权限的管理
    • 添加角色
    • 添加菜单
    • 添加权限
  • 分配权限
    • 用户关联---修改原系统的用户表

      • 跟rbac的UserInfo user = models.OneToOneField(UserInfo,null=True,blank=True)
      • 给用户分角色
      • 给角色分权限
    • 登录应用权限
      • 登录成功后
      • auth.login(request, obj)ret = init_permission(request, obj)if ret:    return ret
      • 初始化权限信息init_permission函数中修改

        user -> user.user

        permission_query = user.user.roles.filter

      • 应用权限校验中间件
        ‘rbac.middleware.rbac.PermissionMiddleware‘,
  • 应用左侧菜单和面包屑导航
    • 在layout模板中,引用CSS和JS
    • 二级菜单
    • {% load rbac %}{% menu request %}
    • 应用路径导航
    • {% breadcrumb request %}
  • 权限控制到按钮级别
    • {% load rbac %}判断 filter  判断里面只能用filter 只能一个一个判断{% load rbac %}?{% if request|has_permission:‘add_customer‘ %}<a href="{% url ‘add_customer‘ %}?{{ query_params }}" class="btn btn-primary btn-sm">添加</a>{% endif %}
  • 使用注意事项
    • 用户注册后 对应在rbac中的UserInfo创建用户 和 原系统的用户做一对一关联
    • 菜单 父权限 子权限 的层级关系

原文地址:https://www.cnblogs.com/xiao-xue-di/p/9913104.html

时间: 2024-10-27 11:55:45

权限管理的三级菜单的流程及使用流程的相关文章

基于吉日嘎底层架构的Web端权限管理操作演示-菜单模块管理

按照顺序,这一篇介绍菜单模块管理,主要演示如下操作: 新增.修改.锁定.解锁.删除.撤销删除 排序 角色成员管理 用户成员管理 导出菜单模块数据 也许你会问,你在这自吹自擂,你这个BS的权限管理有啥缺点不?其中一个美中不足之处:没有批量增加权限Action(或者叫Operation)的地方,下一个版本会加上. 演示视频如下: 优酷视频地址,手机无法播放的点击这里:http://v.youku.com/v_show/id_XMTc0MzMxODk1Mg==.html 下一篇会继续讲解组织机构管理

单点登录与权限管理本质:权限管理介绍

前面几篇文章介绍了单点登录的本质,包括cookie.session.重定向的基本概念,单点登录的基本交互流程,cookie的重要性和安全问题.单点登录能够确保:必须通过身份验证后,才能访问网站,且访问多个系统时,只需要登录一次. 一般系统都会有多个角色,不同角色可访问的系统功能不同,通过给用户分配不同角色,决定用户可访问的系统功能. 继续介绍「单点登录与权限管理」系列的第一部分:单点登录与权限管理本质,本篇说说权限管理,主要从以下几个方面介绍: 权限管理的一般模型 权限验证范围 Shiro基本架

C#反射、方法调用、自动调用方法、根据按钮名称调用方法、C#按钮权限管理

根据按钮名称,直接调用方法,适用于用户对按钮的操作权限管理. /// <summary> /// 菜单按钮点击事件 /// </summary> void usrMenu1_UserControlMenuItemClick(object sender, EventArgs e) { #region MyRegion ////BtnGetParam 获取参数 //if (Nbi.Name == "BtnGetParam") //{ // BtnGetParam_C

从零开始——基于角色的权限管理01(补充)

此博文较为详细的介绍从零开始--基于角色的权限管理01文中的两个部分的流程(解释代码). 1) index.jsp中提交跳转action action的login,获取jsp页面传过来的用户名密码和验证码,进行验证 首先到userDao中,执行login方法,判断是否存在这组用户名和密码 接着到roleDao中,执行getRoleNameById以获取角色名 最后,进入main.jsp中 2)在main.jsp中,有一个树的显示,再次进入authServlet中执行menuAction   先后

权限管理架构设计及实现思路

规划权限管理至少实现菜单权限.界面权限.动作权限(按钮).服务权限. 研究如何实现数据权限等细粒度权限. (1)系统菜单管理 EF架构~性能高效的批量操作(Insert篇)

权限管理---设计分析以及具体细节

权限管理---设计分析以及具体细节 说起权限我们大家都知道,不一样的角色会有不一样的权限.比如就像学生管理系统一样,管理员,老师,学生之间的权限都是不一样的,那么展示的页面也是不一样的.所以,我们现在来看看具体操作. 目标:生成一个独立的组件,到哪都能用 一.先创建一个 项目,建一个app01和rbac的应用 二.表结构设计 1.先看配置文件合适不,给创建的rbac在配置文件里面设置一下   找到INSTALLED_APPS=['rbac'] 配置静态文件 2.设计表结构 models中创建类:

后台菜单和权限管理

主要php文件: 1,admin/includes/inc_menu.php ECSHOP管理中心菜单数组--配置菜单组及URL 2,languages/zh_cn/admin/common.php ECSHOP管理中心共用语言文件--配置菜单显示名 3,admin/includes/inc_priv.php ECSHOP权限对照表--将菜单action与权限绑定   4,languages/zh_cn/admin/priv_action.php ECSHOP权限名称语言文件---配置权限显示的

菜单管理,权限管理,用户管理界面设计

提出问题! 1每个界面需要展示哪些问题? 1.1以哪种方式展示? 每个界面会进行哪些操作? 好了,带着问题进行思考,进行设计 .先来简单的用户管理界面来说,我需要展示用户(管理员)的信息. 方式是:表格形式,需要进行的是对用户的增加,删除,修改 ,模糊查询,以及赋予角色权限. 在菜单管理界面,我需要展示该用户所能操作的菜单详情,分别展示top 菜单 和top 菜单下的子菜单,和菜单项详情 ,在子菜单 的div 内添加 右键事件,在top 里面有一个新增,修改按钮,菜单项详情不可编辑,新增时弹出d

前后端分离进行权限管理之后端生成菜单和权限信息(二)

一.初始化菜单.权限信息 在进行用户名和密码验证成功后就进行权限和菜单的初始化,生成该用户的菜单和权限数据. class LoginView(APIView): authentication_classes = [] # 登陆页面免认证,其余的已经全局配置 def post(self, request, *args, **kwargs): ret = { "data": {}, "meta": { "code": 2001, "mess