權限組件 1 項目與應用 一個項目,能夠有多個應用 一個應用,能夠在多個項目下 前提:應用是組件!! 2 什麼是權限? 一個包含正則表達式url就是一個權限 who what how ---------->True or Flase UserInfor id name pwd permission=models.manytomany(Permission) 多對多 id name pwd 1 egon 123 2 alex 456 3 A 111 4 B 222 5 C 333 6 D 444 Permission id url=..... title=.... id url title 1 "/users/" "查看用戶" 2 "/users/add/" "添加用戶" 3 "/customer/add" "添加客戶" UserInfor_permission id user_id permission_id id user_id permission_id 1 1 1 2 1 2 3 2 2 4 3 1 5 3 2 6 3 3 7 4 1 8 4 2 9 4 3 10 5 1 11 5 2 12 5 3 13 6 1 14 6 2 15 6 3 16 7 1 17 7 2 18 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.....") 這樣作 是否 有問題? 假設:10人 。。。 應該,不一樣的角色有不一樣的權限! 不要給人定權限, 應該給角色定權限 rbac 正確的 見 版本2 ------------------------------------------------------------ # 版本2: UserInfor id name pwd roles = manytomany() 多對多 name pwd egon 123 alex 456 alex 456 alex 456 Role id title=....... permissions = manytomany() 多對多 id title 1 銷售員 UserInfor2Role id user_id role_id 1 1 1 Permission id url=..... title=.... id url title 1 "/users/" "查看用戶" 2 "/users/add/" "添加用戶" 3 "/customer/add" "添加客戶" Role2Permission id role_id permission_id 1 1 1 2 1 2 3 1 3 rbac(role-based access control) app01 作的是項目相關的邏輯內容 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(role-based access control)html
基於角色的權限訪問控制 正則表達式
1.新建一個應用:
startapp rbac
INSTALLED_APPS = [
...
'app01.apps.App01Config',
'rbac.apps.RbacConfig',
]
makemigrations
migrate
models.py數據庫
from django.db import models 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) permission = 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
1.前提
createsuperuser
(yuan yuan1234)
admin.pydjango
from django.contrib import admin # Register your models here. from .models import * admin.site.register(User) admin.site.register(Role) admin.site.register(Permission)
1.在session中註冊用戶ID
request.session['user_id'] = user.pk
2.初始化 permission_list 並註冊到session 中
initial_session(user,request)
rbac/service/permission.py
def initial_session(user, request): permission = user.roles.all().values('permission__url').distinct() # print(permission) # 去重後的 全部權限!! 將權限 存在 session 中!! # <QuerySet [{'permission__url': '/users/'}, {'permission__url': '/users/add'}]> permission_list = [] for item in permission: permission_list.append(item['permission__url']) print(permission_list) # ['/users/', '/users/add'] request.session['permission_list'] = permission_list
注意點:session
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'}]>
views.py
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中註冊用戶ID request.session['user_id'] = user.pk # 初始化 permission_list 並註冊到session 中 initial_session(user,request) return HttpResponse('登陸成功') return render(request,'login.html')
MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
'rbac.service.rbac.ValidPermission',
]
注意點:app
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('無訪問權限!')
rbac/service/rbac.py
# -*- coding:utf-8 -*- from django.shortcuts import HttpResponse, render, redirect from django.utils.deprecation import MiddlewareMixin import re class ValidPermission(MiddlewareMixin): def process_request(self,request): current_path = request.path_info # 白名單,不須要任何權限的url valid_url_list = ['/login/', '/reg/', '/admin/.*'] for valid_url in valid_url_list: ret = re.match(valid_url, current_path) if ret: return # 校驗是否登陸 user_id = request.session.get('user_id') if not user_id: return redirect('/login/') # 校驗權限 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('無訪問權限!')