1、rbac权限组件-初识, 中间件校验1
生活随笔
收集整理的這篇文章主要介紹了
1、rbac权限组件-初识, 中间件校验1
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、權限組件rbac
1、什么是權限
1 項目與應用
2 什么是權限?
一個包含正則表達式url就是一個權限
who what how ---------->True or Flase
?
2、版本1:用戶表與權限url表 對應關系
# 版本1UserInforname pwdpermission=models.manytomany(Permission)name pwd egon 123 alex 456 A 111B 222C 333D 444Permissionurl=.....title=....id url title1 "/users/" "查看用戶"2 "/users/add/" "添加用戶"3 "/customer/add" "添加客戶"UserInfor_permissioniduser_idpermission_id id user_id permission_id1 1 1 2 1 23 2 24 3 15 3 26 3 34 4 15 4 26 4 34 5 15 5 26 5 34 6 15 6 26 6 34 7 15 7 26 7 3?
?
示例:登錄人:egon訪問url:http://127.0.0.1:8000/users/ def users(request):user_id=request.session.get("user_id")obj=UserInfor.objects.filter(pk=user_id).first()obj.permission.all().valuelist("url")return HttpResponse("users.....")?
3、版本2: 用戶--》角色--》權限
UserInforname pwdrolesname pwd egon 123 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 alex 456 Roletitle=....... permissions=......id title1 銷售員UserInfor2Roleid user_id role_id 1 1 1Permissionurl=.....title=....id url title1 "/users/" "查看用戶"2 "/users/add/" "添加用戶"3 "/customer/add" "添加客戶"Role2Permissionid role_id permission_id 1 1 12 1 23 1 33 rbac(role-based access control)
?
2、代碼實現
1)項目目錄結構
2)數據庫表
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.nameclass Role(models.Model):title = models.CharField(max_length=32)permissions = models.ManyToManyField(to="Permission")def __str__(self):return self.titleclass Permission(models.Model):title = models.CharField(max_length=32)url = models.CharField(max_length=32)def __str__(self):return self.title?
?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)?
?
?3、登錄驗證
1、session中注冊用戶,權限
1.在session中注冊用戶IDrequest.session['user_id'] = user.pk
2.初始化 permission_list 并注冊到session 中
initial_session(user,request)
注意點:
permission = user.roles.all().values('permission__url').distinct() 1.values:temp = []
for role in user.roles.all(): # < QuerySet[ < Role: 保潔 >, < Role: 銷售 >] >
temp.append({
'title':role.title
'permission__url': role.permission__url.all()
})
return temp
2.values 不會去重!!
<QuerySet [{'title': '保潔', 'permission__url': '/users/'},
{'title': '銷售', 'permission__url': '/users/'},
{'title': '銷售', 'permission__url': '/users/add'}]>
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如何構造?抄襲
?
?
?
?
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 reflag = Falsefor permission in li:permission = "^%s$" % permissionret = re.match(permission, c_path)if ret:flag = Truebreakif flag:print("success")# ret = re.match("/users/", "/users/delete/9") ret = re.match("^/users/$", "/users/delete/9") print(ret)?
?
3、admin如何驗證:302重定向?
?
?
3、構建中間件
?
# -*- coding: utf-8 -*- # @Time : 2018/08/11 0011 9:04 # @Author : Venicidimport refrom django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse, redirectclass ValidPermission(MiddlewareMixin):def process_request(self, request):# 當前訪問路徑current_path = request.path_info# 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 None# 2、校驗是否登錄user_id = request.session.get("user_id")if not user_id:return redirect('/login/')# 3、校驗權限permission_list = request.session.get("permission_list",[])flag = Falsefor permission in permission_list:permission = "^%s$" % permissionret = re.match(permission, current_path)if ret:flag = Truebreakif not flag:return HttpResponse("沒有訪問權限")return None?
?4、views視圖,url
?
url
from django.contrib import admin from django.urls import path,re_pathfrom app01 import viewsurlpatterns = [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_infoflag = Falsefor permission in permission_list:permission = "^%s$"%permissionret = re.match(permission, current_path)if ret:flag = Truebreakif not flag:return HttpResponse("沒有訪問權限")"""return HttpResponse('add user')def roles(request):role_list = Role.objects.all()print(role_list)# 方式2 middleware"""# 方式1permission_list = request.session["permission_list"] # # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']current_path = request.path_infoflag = Falsefor permission in permission_list:permission = "^%s$"%permissionret = re.match(permission, current_path)if ret:flag = Truebreakif 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())?
?
?5、注意點
注意點:
1.白名單,不需要任何權限的urlvalid_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.nameclass Role(models.Model):title=models.CharField(max_length=32)permissions=models.ManyToManyField(to="Permission")def __str__(self): return self.titleclass 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 = Falsefor permission in permission_list:permission = "^%s$" % permissionret = re.match(permission, current_path)if ret:flag = Truebreakif not flag:return HttpResponse("沒有訪問權限!")return None?
?
?
轉載于:https://www.cnblogs.com/venicid/p/9458776.html
總結
以上是生活随笔為你收集整理的1、rbac权限组件-初识, 中间件校验1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到自己哭的特别伤心是什么意思
- 下一篇: IOPLL动态重配