RBAC 升级版

预期要求

  前端在无权限时不在提供操作标签

  更改部分硬编码

  实现更加精准的权限控制

未改动前的版本

在这里 ⬇

Django_rbac_demo 权限控制组件框架模型

具体更改

数据库结构更改:

  对 permission 表新增两个字段 用于分类具体控制表(group)  以及当前操作行为 (action)

  增加新表 permissiongroup 用来保存控制表字段

models.py 

from django.db import models

# Create your models here.

class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
roles = models.ManyToManyField(to="Role") def __str__(self): return self.name class Role(models.Model):
title = models.CharField(max_length=32)
permissions = models.ManyToManyField(to="Permission") def __str__(self): return self.title class Permission(models.Model):
title = models.CharField(max_length=32)
url = models.CharField(max_length=32)
action = models.CharField(max_length=32, default="")
group = models.ForeignKey("PermissionGroup", default=1) def __str__(self):return self.title class PermissionGroup(models.Model):
title = models.CharField(max_length=32) def __str__(self): return self.title

permission.py

   表结构更改后,后台可利用的数据更多。传回一个字典。

   以及需要 数据处理成便于操作的形式

"""
为了解耦,将处理权限的代码保存在组件里面
""" def initial_session(user,request): """
方案1
不好用,只用一个权限字段实在功能有限
     已被淘汰
""" # # 查看当前用户的所有的权限
# # 因为会有values 的原理会导致有重复需要去重
# ret = user.roles.all().values("permissions__url").distinct()
# permission_list = []
# # 将所有的权限保存在一个列表里面,稍微处理下数据便于操作
# for i in ret:
# permission_list.append(i["permissions__url"])
# # 把用户的用户权限保存在 session 里面
# request.session["permission_list"] = permission_list """
方案2
"""
# permission__group_id permission表 的group 字段 因为外键会后面加个 ”_id“ 别忘了啊
# 取出来当前用户的权限,每个权限对应的属性
permissions = user.roles.all().values(
"permissions__url",
"permissions__group_id",
"permissions__action",).distinct()
# 对拿到的数据进行数据处理
permission_dict = {}
for i in permissions:
gid = i["permissions__group_id"]
if gid not in permission_dict:
permission_dict[gid] = {
"urls": [i["permissions__url"], ],
"actions": [i["permissions__action"], ]
}
else:
permission_dict[gid]["urls"].append(i["permissions__url"])
permission_dict[gid]["actions"].append(i["permissions__action"])
request.session["permission_dict"] = permission_dict

rbac.py 

  对传回的数据进行权限验证

import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect """
写在中间件里面可以完全避免每次都要重复校验的问题
在请求来的时候进行校验,因此要写在 process_request 方法里面
""" class ValidPermission(MiddlewareMixin):
def process_request(self, request):
# 当前访问路径
current_path = request.path_info
"""
检查是否属于白名单
admin 的内部流程
不允许一上来就访问首页,必须要跳转到 登陆页面
http://127.0.0.1:8000/admin/login/?next=/admin/
第二次跳转到登录页面的请求如果没有被定义可通过就会被拦截
无法只使用 admin 为过滤选项
不能用 in 单纯的判断,还是要用到正则处理
需要放过所有 admin 开头的 url
"""
valid_url_list = ["/login/", "/reg/", "/admin/.*"]
for valid_url in valid_url_list:
ret = re.match(valid_url, current_path)
if ret:
# 中间件 return None 表示这个中间件已经执行完毕
return None """
校验是否登录
对于没有登陆的用户返回报错应该是让他去登陆
"""
user_id = request.session.get("user_id")
if not user_id:
return redirect("/login/") # """
# 校验权限 1 permission_list
# 在编辑,以及删除页面的时候 url 不是固定的,
# 会有内含的参数,因此权限列表里面不能仅仅是写死的url
# 也不能再单纯的用 in 来判断。还是要靠正则来处理
# 将权限列表里面的权限信息用 正则表达式来保存
# 然后对访问页面进行验证是否可以通过来处理
# """
# permission_list = request.session.get("permission_list",[])
# flag = False
# for permission in permission_list:
# permission = "^%s$" % permission
# ret = re.match(permission, current_path)
# if ret:
# flag = True
# break
# if not flag:
# return HttpResponse("没有访问权限!")
# return None """
校验权限 2 permission_dict
"""
permission_dict = request.session.get("permission_dict")
for i in permission_dict.values():
urls = i["urls"]
for reg in urls:
reg = f"^{reg}$"
ret = re.match(reg, current_path)
if ret:
# 加一个自定义的 actions 属性在里面
request.actions = i["actions"]
return None
return HttpResponse("没有访问权限!")

views.py

   封装一个 Per 类便于前端更方便的取数据

from django.shortcuts import render,HttpResponse
import re
# Create your views here.
from rbac.models import *
from rbac.service.perssions import * class Per():
def __init__(self,actions):
self.actions = actions def add(self):
return "add" in self.actions def delete(self):
return "del" in self.actions def edit(self):
return "edit" in self.actions def cat(self):
return "cat" in self.actions
def users(request):
user_list = User.objects.all()
# permission_dict = request.session["permission_dict"]
# 查询当前登陆人的名字
id = request.session.get("user_id")
user = User.objects.filter(id=id).first()
per = Per(request.actions)
return render(request, "users.html",locals()) def add_user(request):
permission_list = request.session["permission_list"]
return HttpResponse("add user.....") def del_user(request,id):
return HttpResponse(f"del_user: {id}") def roles(request):
role_list = Role.objects.all()
per = Per(request.actions)
return render(request,"roles.html",locals()) def login(request):
print("login")
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
# 拿到当前用户对象
user = User.objects.filter(name=user, pwd=pwd).first()
if user:
# 把用户的id 保存在 session 里面
request.session["user_id"] = user.pk
# 查询当前用户的所有的权限
initial_session(user, request)
return HttpResponse("登录成功!")
return render(request, "login.html",locals())

 users.html 

   前端页面基于 per 对象的 actions 控制才判断是否对标签进行显示

{% extends "base.html" %}
{% block con %}
<h4>用户列表</h4> {% if per.add %}
<a href="/users/add/" class="btn btn-primary">添加用户</a>
{% endif %}
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>角色</th>
<th>操作</th>
</tr>
</thead> <tbody>
{% for user in user_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.name }}</td>
<td>
{% for role in user.roles.all %}
{{ role.title }}
{% endfor %}
</td>
<td>
{% if per.delete%}
<a href="/users/delete/{{ user.pk }}/" class="btn btn-danger">删除</a>

{% endif %}
{% if per.edit %}
<a href="" class="btn btn-warning">编辑</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

Django_RBAC_demo2 升级版权限控制组件的更多相关文章

  1. 基于.netstandard的权限控制组件

    基于.netstandard的权限控制组件 Intro 由于项目需要,需要在 基于 Asp.net mvc 的 Web 项目框架中做权限的控制,于是才有了这个权限控制组件. 项目基于 .NETStan ...

  2. Django_rbac_demo 权限控制组件框架模型

    rbac 权限控制组件 基于角色的权限控制 本质每个权限即为一个 URL 项目组件结构 表结构 Role (title, permission) -(ManyToManyField)-   User  ...

  3. rbac权限控制组件实现控制的基本原理图

    今天先整理一个rbac的权限控制的原理图上来 代码 后面就不透漏了,但是实现的方法有很多种,我这个只是其中一种的一部分!

  4. Python 目录指引

    1.0 Python 基础整合 1.1 变量 1.2 数据类型 1.3 基础语法 1.4 文件操作 1.5 函数 1.6 生成器 1.7 迭代器 1.8 装饰器 1.9 字符集 2.0 Python ...

  5. 仿SiteMap实现Asp.net 网站的菜单和权限管理

    在Asp.net中,SiteMap用于站点导航,可以与Menu等控件一起使用实现网站的菜单和权限管理.但是SiteMap提供的方法都是只读的,无法再运行时修改(菜单)导航文件,需要手动修改配置web. ...

  6. 实现对ASP.NETMvc及Asp.NetCore的权限控制

    AccessControlHelper Build Status Intro 由于项目需要,需要在 基于 Asp.net mvc 的 Web 项目框架中做权限的控制,于是才有了这个权限控制组件. 项目 ...

  7. ant design pro (十六)advanced 权限管理

    一.概述 原文地址:https://pro.ant.design/docs/authority-management-cn 权限控制是中后台系统中常见的需求之一,你可以利用我们提供的权限控制组件,实现 ...

  8. Django - 权限(2)- 动态显示单级权限菜单

    一.权限组件 1.上篇随笔中,我们只是设计好了权限控制的表结构,有三个模型,五张表,两个多对多关系,并且简单实现了对用户的权限控制,我们会发现那样写有一个问题,就是权限控制写死在了项目中,并且没有实现 ...

  9. 【DRF权限】

    目录 权限的详细用法 我们都听过权限,那么权限到底是做什么的呢. 我们都有博客,或者去一些论坛,一定知道管理员这个角色, 比如我们申请博客的时候,一定要向管理员申请,也就是说管理员会有一些特殊的权利, ...

随机推荐

  1. Android 性能优化之工具和优化点总结

    Android性能优化学习 最近公司主抓性能优化工作,借此春风也学习到了许多Android性能优化方面的知识.由于组内队友的给力,优化的成果也是比较喜人.同时也学习和实践了不少知识,特此记录. 1.性 ...

  2. Windows系统下搭建Git本地代码库

    近由于工作需要,要把工作代码做一下版本管理.工作代码也不方便放到github上,也不想付费建私密库,公司也没几个人,所以就想着搭建一个本地Git版本库,来做版本管理.搭建过程如下. 系统环境:Dell ...

  3. python 实例六

    https://www.cnblogs.com/evablogs/p/6783498.html 题目:斐波那契数列. 程序分析:这个数列从第3项开始,每一项都等于前两项之和.故 n=1,2,f=1 n ...

  4. 为什么不使用github的wiki而是使用mkdocs做文档管理?

    为什么不使用github的wiki而是使用mkdocs做文档管理? 目前 KSFramework 是使用mkdocs来做在线文档 而非使用github的wiki,这是为什么呢? 在windows下搭建 ...

  5. A Deep Learning-Based System for Vulnerability Detection

    本篇文献作者提出了一种基于深度学习来检测软件漏洞的方案.       摘要:作者开始基于深度学习的漏洞检测研究,是为了减轻专家手工定义特性的繁琐任务,需要制定一些指导性原则来适用于深度学习去进行漏洞探 ...

  6. SQLServer之PRIMARY KEY约束

    PRIMARY KEY约束添加规则 1.在表中常有一列或多列的组合,其值能唯一标识表中的每一行,这样的一列或多列成为表的主键(PrimaryKey). 2.一个表只能有一个主键,而且主键约束中的列不能 ...

  7. const int *p;int *const p;区别及用法

    在单片机程序设计中,我们经常会用到const这个关键字,在有些单片机的编译器中可能会是code(比如51系列单片机),但我们在学习C语言的时候,首先还是先学到的const.我们知道,const关键字的 ...

  8. 英语口语练习系列-C12-不了解

    词汇 air [eə(r)] n. 空气 fresh air 新鲜的空气 warm air 暖暖的空气 I like to air the room. 我喜欢给房间通气. on the air 正在播 ...

  9. 数据库【mysql】之pymysql

    安装模块 pip install pymysql 导入模块 import pymysql 创建链接 conn = pymysql.connect(host=') 创建索引 cursor = conn. ...

  10. 最小化spring XML配置,Spring提供了4种自动装配策略。

    1.ByName自动装配:匹配属性的名字 在配置文件中的写法: <bean name="course" class="course类的全包名">&l ...