rbac之 权限粒度控制到按钮级别:  这里的意思就是 如果当前用户,没有这个权限。 那么这个相对应的这个按钮的权限, 就不应该展示。看都不能给看到。

思路:
  为每一个权限,设置一个别名。  这里是这的别名。 要与 路由控制器中的,每条路径的 别名保持一直
  模板中每一个按钮标签的位置,进行 if 判断。 判断这个别名是否在当前用户的,权限字典中。 如果有显示这个按钮。如果没有那就不显示

数据表,进行更改:

class Permission(models.Model):
"""
权限表 一级菜单的表
"""
title = models.CharField(verbose_name='标题', max_length=32)
url = models.CharField(verbose_name='含正则的URL', max_length=128)
name = models.CharField(verbose_name="权限别名", max_length=32, unique=True)
menu = models.ForeignKey(verbose_name="所属菜单", to="Menu", null=True, blank=True, on_delete=models.CASCADE)
pid = models.ForeignKey(verbose_name="关联权限", help_text="对于非菜单权限,需要确定当前权限归属于哪一个,父权限",
to="Permission", null=True, blank=True, on_delete=models.CASCADE, ) def __str__(self):
return self.title

Permission的最终形态。(以后想改 再改喽)

然后,为了比较的方便。我对 登录时的,保存session权限列表的步骤。 进行更改,让他变成一个字典 key 就是 每个权限的别名 name字段

def init_permission(current_user, request):
''' 二级菜单,实现
:param current_user: 当前请求 用户对象
:param request: 当前请求 数据
:return:
'''
# 2. 权限 初始化
# 根据当前用户信息,获取当前用户所拥有的所有的权限(queryset对象 是不能直接放入,session中的)
permission_queryset = current_user.roles.filter(permissions__isnull=False) \
.values("permissions__id", "permissions__url", "permissions__title", "permissions__name",
"permissions__pid_id", "permissions__pid__title", "permissions__pid__url",
"permissions__menu_id", "permissions__menu__icon", "permissions__menu__title", ).distinct() # 获取权限 和 菜单信息。 权限放在权限列表,菜单放在菜单列表
menu_dict = {}
permission_dict = {}
for item in permission_queryset:
permission_dict[item.get("permissions__name")] = {
"id": item.get("permissions__id"),
"title": item.get("permissions__title"),
"url": item.get("permissions__url"),
"paren_id": item.get("permissions__pid_id"),
"paren_title": item.get("permissions__pid__title"),
"paren_url": item.get("permissions__pid__url"),
} menu_id = item.get("permissions__menu_id")
if not menu_id:
continue node = {"id": item.get("permissions__id"), "title": item.get("permissions__title"),
"url": item.get("permissions__url")}
if menu_id in menu_dict:
menu_dict[menu_id]["children"].append(node)
else:
menu_dict[menu_id] = {
"title": item.get("permissions__menu__title"),
"icon": item.get("permissions__menu__icon"),
"children": [node]
}
request.session[settings.PERMISSIONS_SESSION_KEY] = permission_dict
request.session[settings.MENU_SESSION_KEY] = menu_dict

init_permission初始化,权限列表更改为,权限字典!

相应的中间件的地方,也作了修改。 以前因为是一个列表中嵌套的字典格式。 但现在是一个大字典了。 所以 现在循环的是一个字典。

需要for item in permission_dict.values():  直接去循环这个字典的 values 就可以了!其他的 还是原来的配方,还是原来的味道。

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
from django.conf import settings
import re class RbacMiddleware(MiddlewareMixin):
'''用户权限信息的校验''' def process_request(self, request):
'''当用户请求进入时 触发执行'''
'''
1. 获取当前用户请求的url
2. 获取当前用户在session中保存的 权限列表 [......]
3. 当前请求url 在 session中, 就可以,进行访问
''' current_url = request.path_info
for valid_url in settings.VALID_URL_LIST:
if re.match(valid_url, current_url):
return None permission_dict = request.session.get(settings.PERMISSIONS_SESSION_KEY) if not permission_dict:
return HttpResponse("您没有访问权限...请联系管理员") flag = False
url_record = [
{"title": "首页", "url": "#"}
]
for item in permission_dict.values():
reg = "^%s$" % item.get("url")
if re.match(reg, current_url):
flag = True
request.current_selected_permission = item.get("paren_id") or item.get("id")
if not item.get("paren_id"):
url_record.extend([{"title": item.get("title"), "url": item.get("url"), "class": "active"}])
else:
url_record.extend([
{"title": item.get("paren_title"), "url": item.get("paren_url")},
{"title": item.get("title"), "url": item.get("url"), "class": "active"},
])
request.url_record = url_record
break
if not flag:
return HttpResponse("无权访问")

对 rbac.py 中间件,进行修改

最后就是 判断当前这个按钮的别名。 是否在当前用户的权限中有,这个别名:
  解释: 1. 进行判断两个参数, 第一个是当前这个按钮所指向的 url 他的别名好说。 直接写字符串就行。
然后就是,当前用户的权限信息了。 我保存在了  ssession 里面。  具体的就是:
             request.session[settings.PERMISSIONS_SESSION_KEY] = permission_dict  ( 以别名为键的 权限字典 )
    我进行判断时,大概就是这个样子:
      {% if  "costomer_add" in request.session.permissions_url_list_key%}
        .........
      {%endif%}
如果我想要直接进行,判断也是可以的, 但是我的初衷 这个 session-key 是可以在settings中进行配置的。 so我们来自定义一个 模板过滤器吧,因为模板过滤器是可以进行逻辑判断的  另外几个就不行 所以使用 @register.filter 没毛病:

  这个过滤器接收 name  和 request 两个参数:

@register.filter
def has_permission(request, name):
'''
:param request: request对象
:param name: 当前权限的别名
:return:
'''
if name in request.session.get(settings.PERMISSIONS_SESSION_KEY):
return True 如果当前的name别名,在我保存的字典中,return Ture
否则 默认返回 None

rbac_tags 自第一过滤器

ok  过滤器完成: 模板的使用,就简单了:

{% if request|has_permission:"customer_add" %}
  ...........
{% endif %}
这是一种使用的规范,模板过滤器只接收 最多两个参数。 | 之前的时第一个参数。 |之后是这个过滤器的名字 : 之后的是第二个参数。 这中间不要加空格
{% extends 'layout.html' %}
{% load rbac_tags %}
<div class="btn-group" style="margin: 5px 0">
{% if request|has_permission:"customer_add" %}
<a class="btn btn-default" href="/customer/add/">
<i class="fa fa-plus-square" aria-hidden="true"></i> 添加客户
</a>
{% endif %}
{% if request|has_permission:"customer_aimport" %}
<a class="btn btn-default" href="/customer/import/">
<i class="fa fa-file-excel-o" aria-hidden="true"></i> 批量导入
</a>
{% endif %}
</div>

对每一个按钮的 地方都加上,这样的一个判断。就OK啦

然后, 有一点。 选项这里, 编辑和删除的操作。
这里应该是  如果当前用户,有 编辑 或 删除任何一个,权限。那么就应该有选项 的 展示。 如果都没有,那么就应该是空的。
依然使用 这个 过滤器:

<table class="table table-bordered table-hover">
<thead>
<tr>
<th>ID</th>
<th>客户姓名</th>
<th>年龄</th>
<th>邮箱</th>
<th>公司</th>
{% if request|has_permission:"customer_edit" or request|has_permission:"customer_del" %}
<th>选项</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for row in data_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.age }}</td>
<td>{{ row.email }}</td>
<td>{{ row.company }}</td>
<td>
{% if request|has_permission:"customer_edit" %}
<a style="color: #333333;" href="/customer/edit/{{ row.id }}/">
<i class="fa fa-edit" aria-hidden="true"></i></a>
{% endif %} {% if request|has_permission:"customer_del" %}
<a style="color: #d9534f;" href="/customer/del/{{ row.id }}/"><i class="fa fa-trash-o"></i></a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>

ok 完美。

rbac之 权限粒度控制到按钮级别的更多相关文章

  1. crm 一级菜单排序,二级菜单选中并且展开,非菜单权限的归属,权限粒度控制到按钮级别

    排序 /rbac/templatetags/rbac.py from django import template from django.conf import settings import re ...

  2. django中权限控制到按钮级别

    权限控制到按钮级别 :          1.思路 :                  由于每个按钮都能认为是一个权限,所以每个按钮都会有一个自己的路径,这些路径都在用户登录时保存在了session ...

  3. rbac组件权限按钮,菜单,可拔插

      1.通用模板 overflow: auto; //在a和b模板中进行切换 a 模板 :左侧菜单跟随滚动条 b模板  左侧以及上不动 **** <!DOCTYPE html> <h ...

  4. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制

    思路: 动态路由实现:在导航守卫中判断用户是否有用户信息,通过调用接口,拿到后台根据用户角色生成的菜单树,格式化菜单树结构信息并递归生成层级路由表并使用Vuex保存,通过 router.addRout ...

  5. Vue多页面 按钮级别权限控制 directive指令控制

    利用driective 构建自己的指令,实现按钮级别权限 项目结构如下: 修改router.js { path: 'schools', name: '列表', component: () => ...

  6. ThinkPHP框架下基于RBAC的权限控制模式详解

    这几天因为要做一个项目,需要可以对Web应用中通用功能进行封装,其中一个很重要的涉及到了对用户.角色和权限部分的灵活管理.所以基于TP框架自己封装了一个对操作权限和菜单权限进行灵活配置的可控制模式. ...

  7. Java生鲜电商平台-RBAC系统权限的设计与架构

    Java生鲜电商平台-RBAC系统权限的设计与架构 说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上 ...

  8. Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制

    一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...

  9. 百万年薪python之路 -- RBAC角色权限设计

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...

随机推荐

  1. unity 解决ScrollRect嵌套滚动问题

    在子级有ScrollRect组件的对象添加以下脚本: using UnityEngine; using System.Collections; using UnityEngine.UI; using ...

  2. 一次linux启动故障记录

    故障背景: 在2.6.32升级内核之后,出现多台设备启动失败,失败的全部都是ssd作为系统盘的机器,bios引导之后,屏幕就黑了,没有打印. 一开是以为是mbr损坏了,所以将启动盘挂载到其他服务器上, ...

  3. webpack异步加载业务模块

    虽然把我们用到的JS文件全部打包一个可以节省请求数,但如果打包后的JS文件过大,那么也容易出现白屏现象,许多操作失灵.而且一些区域是点到才出现,那么相关的JS其实可以剥离出这个大JS文件外.这就涉及到 ...

  4. GIS案例学习笔记-ArcGIS整图大图出图实例教程

    GIS案例学习笔记-ArcGIS整图大图出图实例教程 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 1. 通过出图比例尺(1:2000),地图范围测算图纸大小. 图 ...

  5. quartz 实例

    第一步:添加jar包 第二步:在spring配置文件中添加 <context:annotation-config/> 第三步:编写定时代码 我们通常做Java后台接口,是让前端访问的,让前 ...

  6. EF 1

    安装框架: 在NuGet中安装ef框架,命令:Install-package EntityFramework 数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migratio ...

  7. 终止执行js的方法

    (一)在function里面 (1)return;(2)return false; (二)非function方法里面 alert("before error.");throw Sy ...

  8. day30 UDP协议

    本周安排 周二 socket编程 周三 粘包处理 周四 选课系统 并发编程 周五多道技术 多进程 周六 IPC 互斥锁 常用模块 os* 操作系统 多数是文件操作 os.path 处理文件路径 shu ...

  9. python websocket网页实时显示远程服务器日志信息

    功能:用websocket技术,在运维工具的浏览器上实时显示远程服务器上的日志信息 一般我们在运维工具部署环境的时候,需要实时展现部署过程中的信息,或者在浏览器中实时显示程序日志给开发人员看.你还在用 ...

  10. JS在严格模式和非严格模式的区别

    若想在严格模式下使用JS,需要在文件的第一行加上“use strict”,在实际开发中,常常将“use strict”加入到闭包的内部 具体是: 整个脚本中使用:在这个JavaScript文件开头写' ...