zoukankan      html  css  js  c++  java
  • rbac-基于角色的权限控制系统(8种常用场景再现)

    首先要抛出的问题是在代码世界里什么是权限?

    • url就代表权限

    如何实现权限控制?

    下面详细介绍控制流程

    1.1简单权限控制--表结构

    简单权限控制,三个model,五张表

    权限表permission

    • url 权限 url的地址 正则表达式 ^$
    • title 标题

    角色表role

    • name 角色名称
    • permissions 多对多 关联权限表

    用户表user

    • username 用户名
    • password 密码
    • roles 多对都 关联角色

    角色和权限的关系表

    用户和角色的关系表

    1.2 一级菜单--表结构

    一级菜单: 在permission表中增加is_menu字段,区别该权限是否是菜单

    权限表

    • url 权限 url的地址 正则表达式 ^$

    • title 标题

    • is_menu 是否是菜单

    • icon 图标

    1.3 二级菜单--表结构

    二级菜单: 实现二级菜单功能时,需要增加第六张表menu,在权限表中加入外键,关联menu表,有menu_id 当前的权限是二级菜单 没有menu_id 当前的权限是普通的权限

    菜单表

    • title 一级菜单的名称
    • icon 图标

    权限表

    • url 权限 url的地址 正则表达式 ^$

    • title 标题

    • menu 外键 关联菜单表 有menu_id 当前的权限是二级菜单 没有menu_id 当前的权限是普通的权限

    1.4 二级菜单 对一级菜单进行排序--表结构

    要对一级菜单排序,在menu中加入weight权重字段

    菜单表

    • title 一级菜单的名称

    • icon 图标

    • weight 整型

    1.5 非菜单 权限归属

    权限归属,在menu表中加入parent外键,自关联权限表, 有parent_id当前的权限是子权限, 没有parent_id 当前的权限是父权限 ,即二级菜单

    权限表

    • url 权限 url的地址 正则表达式 ^$
    • title 标题
    • menu 外键-关联菜单表 有menu_id 当前的权限是二级菜单 没有menu_id 当前的权限是普通的权限
    • parent 外键-关联权限表-自关联, 有parent_id 当前的权限是子权限 没有parent_id 当前的权限是父权限 二级菜单

    --表结构:

    • menu 菜单表

      • title 标题
      • icon 图标
      • weight 权限
    • permission 权限表

      • url 权限,url路径,正则表达式 ^$

      • title 标题

      • name url的别名, 唯一

      • menu 外键,--关联菜单表,blank=True,null=True , (二级菜单使用)

        • 存在menu_id,当前的权限是二级菜单,
        • 没有menu_id当前的权限是普通权限
      • parent 自关联, (非菜单权限归属使用)

        • 有menu_id 的就是子权限
        • 没有parent_id就是父权限
      • is_menu 布尔值,一级菜单使用的

      • icon,一级菜单使用的

    • role 角色表

      • name 角色的名称,
      • permission 多对多,关联权限表
    • user用户表

      • username 用户名
      • password 密码
    • role_permission角色与权限的关系表

    • user_role 用户与角色的关系表

    --数据结构(流程+技术点)

    1. 简单的权限控制
    • 登陆成功后保存权限信息到session中

      • 权限数据结构

        permission_list = [{url},]
        
    • 中间件-

      -(校验成功,return None,校验失败继续执行)

      • 获取当前访问的url路径
      • 白名单校验
      • 登录状态的校验
      • 免认证的地址校验
      • 权限的校验
        • 从sission中获取权限
        • 循环权限,正则匹配
    • 模板

      • 母版和继承
    2. 动态生成一级菜单
    • 登录成功保存用户权限到sission中

      • 权限数据结构

        permission_list=[{url},]
        
      • 菜单数据结构

      menu_list=[{url:,title:,icon:,},]
      
    • 中间件

      校验成功,return None,校验失败继续执行

      • 获取当前访问的url路径
      • 白名单校验
      • 登录状态校验
      • 免认证路径的校验
      • 权限的校验
        • 从session中获取权限
        • 循环权限,正则匹配
    • 母版

      • inclusion_tag
      • 动态生成一级菜单
        • 定义inclusion_tag
        • yi曾for循环men_list,生成一级菜单
    3. 动态生成二级菜单
    • 登录成功后保存用户权限到session

      • 权限列表数据结构

        permission_list ={{url:,},}
        
      • 菜单字典数据结构

        menu_dict={一级菜单ID:{
            title:
            icon:
            children:[{
                url:
                title:
            },]
        },}
        
    • 中间件

      • 获取当前访问的url路径
      • 白名单校验
      • 登录状态校验
      • 免认证路径的校验
      • 权限校验
        • 从session中获取权限
        • 循环权限,正则匹配
    • 模板

      • 模板和继承

      • 动态生成二级菜单

        • 自定义inclusion_tag

        • 两层for循环menu_dict.values()

    4. 动态生成二级菜单(一级菜单排序)
    • 登录成功获取用户权限保存到sission中

      • 权限列表数据结构

        permission_list= [{url},]
        
      • 菜单字典数据结构

        menu_dict = {一级菜单的id:{
        	title:
        	icon:
        	weight:
        	children:[{
        		url:
        		title:
        	},]
        },}
        
    • 中间件

      • 中间件
        • 获取当前访问的url路径
        • 白名单校验
        • 登录状态校验
        • 免认证路径的校验
        • 权限校验
          • 从session中获取权限
          • 循环权限,正则匹配
    • 模板

      • 母版和继承

      • 生成二级菜单并对一级菜单排序

        • 自定义inclusion_tag

        • sorted对menu_diact字典排序,添加到有序字典od

        • 两层for循环,返回有序字典od.values(),

    5. 动态生成二级菜单(二级菜单默认选中,展开)
    • 登录成功后保存用户权限到session

      • 权限列表数据结构

        permission_list =  [{url}]
        
      • 菜单字典的数据结构

        menu_dict= {一级菜单id:{
        	title:
        	icon:
        	weight:
        	children:[{
        		url:
                title:
        	},]
        },}
        
    • 中间件

      • 获取当前访问的url地址路径
      • 白名单校验
      • 登录状态检验
      • 免认证地址校验
      • 权限校验
        • 从session中获取权限
        • 循环权限,正则匹配
    • 模板

      • 母版和继承
      • 动态生成二级菜单,并排序,展开
        • 自定义inclusion_tag
        • 获取当前url
        • sorted对menu_diact字典排序,添加到有序字典od
        • 循环一级菜单,加入class='hide'
        • 循环二级菜单,正则匹配url,如果匹配成功
          • 二级菜单加class='active'
          • 一级菜单class=''
        • 两层for循环,返回有序字典od.values()
    6. 动态生成二级菜单(非菜单权限归属,子权限选中二级菜单展开)
    • 登录成功后保存用户权限到session

      • 权限列表数据结构

        permission_list = [{
        	url:
        	id:
        	pid:
        },]
        
      • 菜单字典数据结构

        menu_dict = {一级菜单id:{
        	title:
        	icon:
        	weight:
        	children:[{
        		url:
        		title:
        		id:
        	},]
        },}
        
    • 中间件

      • 获取当前访问的url路径
      • 白名单校验
      • request.current_menu_id = None ---当访问index免认证地址时,保证全部二级菜单闭合
      • 登录状态的校验
      • 免认证的校验
      • 权限的校验
        • 从sission中获取取消权限
        • 循环权限,正则匹配
        • 获取权限列表中的id和pid
          • 当pid不存在时,当前权限是一个二级菜单,把id封装到request中,request.current_menu_id=id --current 当前--
          • 当pid存在时,当前权限是一个二级菜单,把pid,即耳机菜单的id封装到requst中,request.current_menu_id=pid
    • 模板

      • 母版与继承

      • 生成二级菜单,子权限选中二级菜单展开

        • 自定义inclussion_tag

        • 获取当前url

        • sorted 对一级菜单排序,添加到有序字典od

        • 循环一级菜单,加入class='hide'

        • 循环二级菜单,判断request.current_menu_id与二级菜单中的id是否相等

          • 相等时给该二级菜单加入class='active',移除一级菜单中的hide类,class=''
        • 两层for循环,返回od.values()

    7. 路径导航
    • 登录成功保存用户权限到sission中

      • 权限字典数据结构

        permission_dict ={权限id:{   # 可以根据子权限的pid获取父权限的字典
        	url:,
        	id:,
        	pid:,
            title:,
        	},} 
        
      • 菜单字典数据结构

        menu_dict = {一级菜单id:{
        	title:
        	icon:
        	weight:
        	children:[{
        		url:
        		title:
        		id:
        	},]
        },}
        
    • 中间件

      • 获取当前访问的url路径
      • 白名单校验
      • request.current_menu_id=None ---当访问index免认证地址时,保证全部二级菜单闭合
      • request.breadcrumb_list =[{'title':'主页','url':'/index/'},] ---添加免认证信息到路径导航
      • 登录状态校验
      • 免认证地址校验
      • 权限校验
        • 从sission中获取权限
        • 循环权限permissions_dict.vlaues,正则匹配
        • 获取id和pid
          • 如果pid不存在是一个二级菜单,
            • request.current_menu_id = id
            • 封装该二级菜单信息--request.breadcurmb_list.append({'title':i['title'],'url':i['url']})
          • 如果pid存在,是一个子权限
            • 父权限p_permissions = permissions_dict[str('dict')]
            • request.current_menu_id = pid
            • 封装该二级菜单信息--request.breadcurmb_list.append({'title':p_permissions['title'],'url':p_permissions['url']})
            • 封装子权限菜单信息--request.breadcurmb_list.append({'title':i['title'],'url':i['url']})
    • 模板

      • 母版和继承

      • 生成二级菜单,子权限选中二级菜单展开

        • 自定义inclussion_tag

        • 获取当前url

        • sorted 对一级菜单排序,添加到有序字典od

        • 循环一级菜单,加入class='hide'

        • 循环二级菜单,判断request.current_menu_id与二级菜单中的id是否相等

          • 相等时给该二级菜单加入class='active',移除一级菜单中的hide类,class=''
        • 两层for循环,返回od.values()

      • 路径导航

        • 自定义inclusion_tag
        • 获取breadcurmb_list= request.breadcrumb_list
        • 一层for循环 request.breadcrumb_list
    8. 权限控制到按钮级别
    • 登录成功之后保存用户权限到session

      • 权限字典数据结构

        permisssions_dict={url别名:{
        	url:
            id:
            pid:
            pname:
        },}
        
      • 菜单字典数据结构

        menu_dict = {一级菜单id:{
        	title:
        	icon:
        	weight:
        	children:[{
        		url:
        		title:
        		id:
        	},]
        },}
        
    • 中间件

      • 获取当前访问的url路径

      • 白名单校验

      • request.current_menu_id=None

      • request.breadcrumb_list=[{'tittle':'主页','url':'/index/'},]

      • 登录状态校验

        • 从sission中获取权限
        • 循环权限permissions_dict.vlaues,正则匹配
        • 获取id和pid
          • 如果pid不存在,当前url就是二级菜单
            • request.current_menu_id = id
            • request.breadcrumb_list.append({'title':i['title'],'url':i['url']})
          • 如果pid存在,当前url就是子权限
            • 获取父权限(二级菜单)信息 p_permissions = permissions_dict[i['pname']]
            • request.current_menu_id = pid
            • request.breadcrumb_list.append({'title':p_permissions['title'],'url':p_permissions['url']})
            • request.breadcrumb_list.append({'title':i['title'],'url':i['url']})
    • 模板

      • 母版和继承

      • 生成二级菜单/一级菜单排序/非菜单权限归属,子权限选中二级菜单展开

        • 自定义inclussion_tag

        • 获取当前url

        • sorted 对一级菜单排序,添加到有序字典od

        • 循环一级菜单,加入class='hide'

        • 循环二级菜单,判断request.current_menu_id与二级菜单中的id是否相等

          • 相等时给该二级菜单加入class='active',移除一级菜单中的hide类,class=''
        • 两层for循环,返回od.values()

      • 路径导航

        • 自定义inclusion_tag
        • 获取breadcurmb_list= request.breadcrumb_list
        • 一层for循环 request.breadcrumb_list
      • 权限控制到按钮

        • 自定义filter --has_permission
        • 判断前端传过来的name in permission_dict,
          • 存在返回True
          • 不存在返回False
        • 在html文件中作判断{% if request|has_permission: name %} { % endif %}
  • 相关阅读:
    从零入门 Serverless | 教你 7 步快速构建 GitLab 持续集成环境
    4 个场景揭秘,如何低成本让容器化应用 Serverless 化?
    如何无缝迁移 SpringCloud/Dubbo 应用到 Serverless 架构
    精准容量、秒级弹性,压测工具 + SAE 方案如何完美突破传统大促难关?
    golang 实现最小二乘法拟合直线
    golang 实现两数组对应元素相除
    js 算数组平均值、最大值、最小值、偏差、标准差、中位数、数组从小打大排序、上四分位数、下四分位数
    ajax传数组后台GO语言接收
    python 画图中文显示问题
    python stats画正态分布、指数分布、对数正态分布的QQ图
  • 原文地址:https://www.cnblogs.com/bigox/p/11203274.html
Copyright © 2011-2022 走看看