1、权限组件rbac

1、什么是权限

1 项目与应用

2 什么是权限?

一个包含正则表达式url就是一个权限

who what how ---------->True or Flase

2、版本: 用户--》角色--》权限

    UserInfor

         name
pwd
roles name pwd
egon
alex
alex
alex
alex
alex
alex
alex
alex Role title=.......
permissions=...... id title
销售员 UserInfor2Role id user_id role_id Permission url=.....
title=.... id url title
"/users/" "查看用户"
"/users/add/" "添加用户"
"/customer/add" "添加客户" Role2Permission id role_id permission_id rbac(role-based access control)

3.数据表的初步设计

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) #权限的url action=models.CharField(max_length=32,default="") #权限操作(add,list,edit,delete)
group=models.ForeignKey("PermissionGroup",default=1,on_delete=models.CASCADE)
def __str__(self):
return self.title class PermissionGroup(models.Model):
title=models.CharField(max_length=32) def __str__(self):
return self.title
 

1)项目目录结构

2)数据库表

3)admin添加数据

创建超级用户 alex

注册数据表

from django.contrib import admin

# Register your models here.

from .models import *

admin.site.register(User)
admin.site.register(Role)
admin.site.register(Permission)

4、登录验证

1、session中注册用户,权限

1.在session中注册用户ID
request.session['user_id'] = user.pk
2.初始化 permission_list 并注册到session 中
initial_session(user,request)
        if 登录成功:
user=User.objects.filter(name=user,pwd=pwd).first()
只要这个user对象存在
initial_session(user,request)通过传入登录的user对象和request
可以把当前登录用户的权限列表和user_id注册到session中。
else:
redirect("/login/") ** 把设置session单独做成一个函数接口降低耦合,只需要传入登录用户的对象。
def initial_session(user,request):
permissions = user.roles.all().values("permissions__url").distinct()
#通过登录用户对象查找到所有的角色对象QuerySet,然后跨表到权限表取到URL,做一个去重
 <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'},  {'permissions__url': '/users/delete/(\\d+)'}]>

注意点:

permission = user.roles.all().values('permission__url').distinct()
 #将这些权限取到对应的URL并且添加到列表中,设置在session中。
permission_list = []
for item in permissions:
permission_list.append(item["permissions__url"])
print(permission_list)
request.session["permission_list"] = permission_list

2、解耦

 
def initial_session(request,user):
permissions = user.roles.all().values("permissions__url").distinct() permission_list = []
for item in permissions:
permission_list.append(item['permissions__url']) print(permission_list) # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)'] request.session["permission_list"] = permission_list """
values : for role in user.roles.all(): # <QuerySet [<Role: 保洁>, <Role: 销售>]>
temp.append({
"title":role.title,
"permissions_url":role.permissions.all()
}) # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'},
# {'title': '销售', 'permissions__url': '/users/'},
# {'title': '销售', 'permissions__url': '/users/add'}]> """
 

 

4、基于中间件的权限校验

1、middleware如何构造

 设置中添加中间件"rbac.service.rbac.ValidPermissionMiddleware"

2、正则匹配

 
from django.test import TestCase

# Create your tests here.

# 当前path 如何与 paths匹配
# 不能用in /users/delete/9
# 正则匹配 li = ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)'] c_path = "/users/delete/9" import re flag = False for permission in li:
permission = "^%s$" % permission
ret = re.match(permission, c_path)
if ret:
flag = True
break if flag:
print("success") # ret = re.match("/users/", "/users/delete/9")
ret = re.match("^/users/$", "/users/delete/9")
print(ret)
 

3、构建中间件

        import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect class ValidPermissionMiddleWare(MiddlewareMixin):
def process_request(self,request):
# 当前访问路径
current_path = request.path_info #1层校验 检查是否属于白名单
valid_url_list=["/login/","/reg/","/admin/.*"]
for valid_url in valid_url_list:
ret=re.match(valid_url,current_path)
if ret:
return None #2层校验 校验是否登录
user_id=request.session.get("user_id")
if not user_id:
return redirect("/login/") # 3层校验校验权限
permission_list = request.session.get("permission_list",[])
#['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)'] flag = False
for permission in permission_list:
#此处做一个RE拼接,不然容易匹配失败
permission = "^%s$" % permission
ret = re.match(permission, current_path)
if ret:
flag = True
break
if not flag:
return HttpResponse("没有访问权限!")
#在此处就直接告诉用户没有权限,不再进入视图。
return None

4、views视图,url

url.py

 
from django.contrib import admin
from django.urls import path,re_path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^users/$',views.users),
re_path(r'^users/add/$',views.add_user),
re_path(r'^roles/$',views.roles),
re_path(r'^login/$',views.login),
]
 

views

 
from django.shortcuts import render, HttpResponse

# Create your views here.

from rbac.models import *

def users(request):
user_list = User.objects.all() return render(request, "users.html", locals()) def add_user(request): """
permission_list = request.session["permission_list"] # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
current_path = request.path_info 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 HttpResponse('add user') def roles(request):
role_list = Role.objects.all()
print(role_list) # 方式2 middleware """
# 方式1
permission_list = request.session["permission_list"] # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']
current_path = request.path_info 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 render(request, "roles.html", locals()) from rbac.service.perssions import *
def login(request):
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: ############## 在session中注册用户
request.session['user_id'] = user.pk ############# 在session中注册权限list # 查询当前登录用户的所有角色
# ret = user.roles.all()
# print(ret) # <QuerySet [<Role: 保洁>, <Role: 销售>]> # 查询当前登录用户的所有权限 initial_session(request, user) return HttpResponse("登录成功") return render(request, 'login.html', locals())
 

注意点

1.白名单,不需要任何权限的url
valid_url_list = ['/login/', '/reg/', '/admin/.*']
for valid_url in valid_url_list:
ret = re.match(valid_url, current_path)
if ret:
return 正则匹配 2.校验是否登录,
user_id = request.session.get('user_id')
if not user_id:
return redirect('/login/') 3.校验权限(^ $ / 正则)
permission_list = request.session.get('permission_list',[]) flag = False
for permission in permission_list:
# ['/users/', '/users/add/', '/users/edit/(\\d+)/', '/users/delete/(\\d+)/']
# 需要 ^ $ 限定!!
permission = "^%s$" % permission # 正则
ret = re.match(permission, current_path)
if ret:
flag = True
break if not flag:
return HttpResponse('无访问权限!')
 

4、总结:关于rbac

 
关于rbac: 

    (1) 创建表关系:
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) def __str__(self):return self.title (2) 基于admin录入数据 (3) 登录校验: if 登录成功: 查询当前登录用户的权限列表注册到session中 (4) 校验权限(中间件的应用)
class ValidPermission(MiddlewareMixin): def process_request(self,request): # 当前访问路径
current_path = request.path_info # 检查是否属于白名单
valid_url_list=["/login/","/reg/","/admin/.*"] for valid_url in valid_url_list:
ret=re.match(valid_url,current_path)
if ret:
return None
# 校验是否登录 user_id=request.session.get("user_id")
if not user_id:
return redirect("/login/") # 校验权限
permission_list = request.session.get("permission_list",[]) # ['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)'] 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

rbac权限+中间件的更多相关文章

  1. rbac权限+中间件 初识

    rbac权限+中间件 1.权限组件rbac 1.什么是权限 1 项目与应用 2 什么是权限? 一个包含正则表达式url就是一个权限 who what how ---------->True or ...

  2. CRM项目之RBAC权限组件-day26

    写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...

  3. 基于RBAC权限验证, 中间价middleware实现, views 登录视图代码

    废话不多说  上代码: 基础实现: rom django.shortcuts import HttpResponse, redirect, render from django.http import ...

  4. vue基于d2-admin的RBAC权限管理解决方案

    前两篇关于vue权限路由文章的填坑,说了一堆理论,是时候操作一波了. vue权限路由实现方式总结 vue权限路由实现方式总结二 选择d2-admin是因为element-ui的相关开源项目里,d2-a ...

  5. [七年技术总结系列][理论篇]-RBAC权限模型由浅入深

    权限部分将分两章介绍,第一章由浅入深介绍权限理论知识及应用,第二章介绍具体实现.后期再讲述中间件的使用时,还会插入一些权限内容,本质上属于中间件的应用. 权限模块是业务系统最常见.最基本的子集.本章假 ...

  6. rbac权限组件整合到实际项目的全过程详述

    rbac简介 项目的GitHub地址 欢迎Download&Fork&Star:https://github.com/Wanghongw/CombineRbac 另外,本文只简单介绍一 ...

  7. 22-1 rbac权限设计

    一 表结构设计 from django.db import models # Create your models here. from django.db import models # Creat ...

  8. RBAC权限分配

    RABC:基于角色的权限访问控制(Role-Based Access Control) 一般在登录系统认证通过后,会先确定的该用户的操作权限,判断用户的后续操作是否合法! RABC至少需要三张表:用户 ...

  9. RBAC权限管理

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

随机推荐

  1. php中jpgraph库的使用

    用Jpgraph,只要了解它的一些内置函数,可以轻松得画出折线图.柱形图.饼状图等图表. 首先要保证PHP打开了Gd2的扩展: 打开PHP.ini,定位到extension=php_gd2.dll,把 ...

  2. Linux系统将服务器时间与网络时间同步

    遇到一种情景,就是多台服务器之间的时间并不是同步的,有的快有的慢,这时候就要用到网络时间了, 登陆到服务器上,输入命令date可以查询服务器的时间,需要同步的时候需要安装ntpdate; 1.  安装 ...

  3. June 11. 2018 Week 24th, Monday

    Love is the beauty of the soul. 爱是灵魂之美. From Saint Augustine. The complete version of this quote goe ...

  4. Lua5.1 升级 Lua5.3 升级 小结

    Lua的版本差异确实是比较让人头疼的事情,之前在移动端一直采用Android下使用LuaJit,Ios下使用Lua5.1.这次升级到Xlua(lua5.3版本)主要有两方面的原因:一是ulua后续维护 ...

  5. CSS染色图标(图片)

    之前一直以为用background引入的图标无法染色(非字体图标),现在才知道有黑科技可以用,就是利用drop-shadow. 代码示例 <!DOCTYPE html> <html& ...

  6. 《Java大学教程》--第1章 步入Java世界

    1.2 软件:用于计算机执行的指令的集合称之为程序(program).单个程序或者一组程序称之为软件(software)1.3 编译:计算机的语言称为机器码(machine code).用编译器(co ...

  7. 【存储】RAID磁盘阵列选择

    RAID磁盘阵列(Redundant Arrays of Inexpensive Disks) 一个基本思想:将多个容量较小.相对廉价的磁盘进行有机组合,从而以较低的成本获得与昂贵大容量磁盘相当的容量 ...

  8. 数位dp D - Count The Bits

    题目:D - Count The Bits 博客 #include <cstdio> #include <cstring> #include <cstdlib> # ...

  9. 安利一个_Java学习笔记总结

    javaIO 字符编码 多线程 线程池 ArrayList遍历方式 LinkedList遍历方式 Vector遍历方式 Vector, ArrayList, LinkedList 的区别是什么? Ha ...

  10. centos7下kubernetes(1。kubernetes---start)

    kubernetes官网:https://kubernetes.io/docs/home/ 也是怀着不情愿的心情,要开始kubernetes了,本身是非常热爱技术,尤其是容器技术,可能是最近有点累和懈 ...