low版權(quán)限管理結(jié)構(gòu)
1.創(chuàng)建rbac應(yīng)用
1.先看配置文件合適不,給創(chuàng)建的rbac在配置文件里面設(shè)置一下找到
INSTTLED_APPs=['rbac']
2.配置靜態(tài)文件
2.在models中創(chuàng)建對象
models
from django.db import models
class Permission(models.Model):
"""
權(quán)限表
"""
title = models.CharField(verbose_name='標題',max_length=32)
url = models.CharField(verbose_name="含正則URL",max_length=64)
is_menu = models.BooleanField(verbose_name="是否是菜單")
class Meta:
verbose_name_plural = "權(quán)限表"
def __str__(self):
return self.title
class User(models.Model):
"""
用戶表
"""
username = models.CharField(verbose_name='用戶名',max_length=32)
password = models.CharField(verbose_name='密碼',max_length=64)
email = models.CharField(verbose_name='郵箱',max_length=32)
roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
class Meta:
verbose_name_plural = "用戶表"
def __str__(self):
return self.username
class Role(models.Model):
"""
角色表
"""
title = models.CharField(max_length=32)
permissions = models.ManyToManyField(verbose_name='具有的所有權(quán)限',to='Permission',blank=True)
class Meta:
verbose_name_plural = "角色表"
def __str__(self):
return self.title
models
3.基于Django admin錄入權(quán)限數(shù)據(jù)
注意錄入信息要先創(chuàng)建個超級用戶
python3 manage.py createsuperuser
-用戶名 root
-密碼:peak2345
注意税稼;需要在admin.py中做如下操作(只針對從用admin導入數(shù)據(jù)的時候配置疲扎,當然也可以直接添加)
from django.contrib import admin
from . import models
admin.site.register(models.Permission)
admin.site.register(models.User)
admin.site.register(models.Role)
4.用戶登錄程序
根據(jù)輸入的用戶名和密碼的到相應(yīng)的user
根據(jù)user對象獲取其擁有的角色和權(quán)限并去重并將權(quán)限表的url放入session中拒垃,將這部分操作的代碼抽取到service包下的init_permission.py下的init_permission(request,user)方法中宴卖,然后在views中調(diào)用該方法既可
- 獲取當前用戶具有的所有權(quán)限(去重)
- 獲取權(quán)限中的url,放置到session中
def init_permission(user,request):
"""
初始化權(quán)限信息捏悬,獲取權(quán)限信息并放置到session中。
:param user:
:param request:
:return:
"""
permission_list = user.roles.values('permissions__title', 'permissions__url', 'permissions__is_menu').distinct()
url_list = []
for item in permission_list:
url_list.append(item['permissions__url'])
print(url_list)
request.session['permission_url_list'] = url_list
init_permission.py
4.中間件的使用
如果不用中間件會有好多個函數(shù)润梯,就有許多重復的代碼过牙,這樣我們可以用中間件來完成
中間件和裝飾器的區(qū)別:
- 中間件用來做批量處理
- 如果函數(shù)不多的話可以用加裝飾器的方法
import re
#:用re去匹配的時候,re.match(/userinfo/,/userinfo/add) #都能匹配到
from django.shortcuts import redirect,HttpResponse
from django.conf import settings
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
class RbacMiddleware(MiddlewareMixin):
def process_request(self,request):
# 1. 獲取當前請求的URL
# request.path_info
# 2. 獲取Session中保存當前用戶的權(quán)限
# request.session.get("permission_url_list')
current_url = request.path_info
# 當前請求不需要執(zhí)行權(quán)限驗證(白名單)
for url in settings.VALID_URL:
if re.match(url,current_url):
return None
permission_list = request.session.get("permission_url_list")
if not permission_list:
return redirect('/login/')
flag = False
for db_url in permission_list:
regax = "^{0}$".format(db_url)
#:那么要記得在匹配正則的時候加個起始符和終止符regex = "^{0}$".format(url)
if re.match(regax, current_url):
flag = True
break
if not flag:
return HttpResponse('無權(quán)訪問')
rbac.py
a.獲取當前訪問的路徑 request.path_info
b.在setting中配置不需要驗證的url--白名單(人人登錄后都能訪問如login admin)然后調(diào)用
VALID_URL = [
"/login/",
"/admin.*"
]
根據(jù)正則判斷當前路徑是否在白名單中纺铭,白名單中的路徑要嚴格控制以什么開頭和什么結(jié)尾寇钉,如果有白名單return none繼續(xù)執(zhí)行后面代碼如果不是直接跳轉(zhuǎn)到登錄
c.不是白名單的話,則要判斷是否登錄舶赔,最簡單的方法就是獲取session
看里面是否為空扫倡,如果為空的話說明沒有登錄直接跳轉(zhuǎn)到登錄,不讓他執(zhí)行后續(xù)的操作
d.url list不為空的話就說明已經(jīng)登陸了,進一步看當前的訪問路徑是否在是否在urllist中竟纳,在的話就說明用戶具有操作該url的權(quán)限否則就說明該用戶沒有
訪問權(quán)限撵溃,直接return HttpResponse("無權(quán)訪問")
注意:中間件創(chuàng)建完成之后疚鲤。需要在settings中的MIDDLEWARE最后添加'rbac.middlewares.rbac.RbacMiddleware',
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'rbac.middlewares.rbac.RbacMiddleware',
]