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. idea使用事项

    1.调用外部jar包 Run/Debug Configurations --- Tomcat Server --- Startup/connection --- Debug 添加“path”变量:** ...

  2. 如何在WIN10内置Ubuntu中有多个terminal

    使用的是tmux来实现在WIN10的内置Ubuntu实现多终端窗口 先安装tmux:sudo apt-get install tumx 启动tmux,tmux 然后就可以在tmux中实现多窗口.其操作 ...

  3. C#检查字符串是否是合法的HTTP URL地址的代码

    在研发过程,把开发过程较好的一些内容片段记录起来,下面的内容是关于C#检查字符串是否是合法的HTTP URL地址的内容,应该是对各位有较大用处. protected string HTTPChecke ...

  4. 前端js面向对象编程以及封装组件的思想

    demo-richbase 用来演示怎么使用richbase来制作组件的例子 作为一名前端工程师,写组件的能力至关重要.虽然javascript经常被人嘲笑是个小玩具,但是在一代代大牛的前仆后继的努力 ...

  5. MySQL 基础知识梳理学习(三)----InnoDB日志相关的几个要点

    1.InnoDB的特点 :(1)Fully ACID (InnoDB默认的Repeat Read隔离级别支持):(2)Row-level Locking(支持行锁):(3)Multi-version ...

  6. 推荐一款MongoDB的客户端管理工具--nosqlbooster

    今天给大家推荐一款MongoDB的客户端工具--nosqlbooster,这个也是我工作中一直使用的连接管理MongoDB的工具.这个工具还有个曾用名--mongobooster.nosqlboost ...

  7. c:\windows\system32\config\systemprofile\desktop 打不开

    Question 重启开机后显示桌面打不开: 再次重启后无效 Solution 打开注册表regedit如下路径,复制Desktop值到 同路径下的Desktop中,再重启.

  8. luajit官方性能优化指南和注解

    luajit是目前最快的脚本语言之一,不过深入使用就很快会发现,要把这个语言用到像宣称那样高性能,并不是那么容易.实际使用的时候往往会发现,刚开始写的一些小test case性能非常好,经常毫秒级就算 ...

  9. 0e开头的md5收集 --------PHP加密模块bug

    ————————————————md5加密—————————————— s878926199a s155964671a s214587387a s214587387a s878926199a s109 ...

  10. Cs231n课堂内容记录-Lecture 8 深度学习框架

    Lecture 8  Deep Learning Software 课堂笔记参见:https://blog.csdn.net/u012554092/article/details/78159316 今 ...