赞
踩
一、基于中间件的权限管理
权限,角色表的创建
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
登录成功session数据采集
sever/perssion.py
def initial_session(user,request):
permissions = user.roles.all().values("permissions__url").distinct() # .distinct()去重
permission_list = []
for item in permissions:
permission_list.append(item["permissions__url"])
print(permission_list)
request.session["permission_list"] = permission_list
views.py
request.session["user_id"]=user.pk
initial_session(user,request)
中间件做权限认证(正则表达式)
import re from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse,redirect 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
在setting中放入自己的中间件
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.service.rbac.ValidPermission"
]
小知识:
1、什么时候该给路径加反斜杠:若没有加杠Django会自己加杠给重定向一次,相当于访问了浏览器两次。去除重定向:APPEND_SLASH = False 在setting.py中配置
二、权限粒度控制
更改数据库结构
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
登录验证:
permissions = user.roles.all().values("permissions__url","permissions__group_id","permissions__action").distinct()
构建permission_dict
原始permission_dict:
permissions: [ {'permissions__url': '/users/add/', 'permissions__group_id': 1, 'permissions__action': 'add'}, {'permissions__url': '/roles/', 'permissions__group_id': 2, 'permissions__action': 'list'}, {'permissions__url': '/users/delete/(\\d+)', 'permissions__group_id': 1, 'permissions__action': 'delete'}, {'permissions__url': 'users/edit/(\\d+)', 'permissions__group_id': 1, 'permissions__action': 'edit'} ]
经过的数据处理函数:
permission_dict= {}
for i in permissions:
id = i.get('permissions__group_id')
if id not in permission_dict:
permission_dict[id] = {
'urls':[i.get('permissions__url'),],
'action':[i.get('permissions__action'),]
}
else:
permission_dict[id].get('urls').append(i.get('permissions__url'))
permission_dict[id].get('action').append(i.get('permissions__action'))
得到最终的数据:
permission_dict = {
1: {
'urls': ['/users/', '/users/add/', '/users/delete/(\\d+)', 'users/edit/(\\d+)'],
'actions': ['list', 'add', 'delete', 'edit']
},
2: {
'urls': ['/roles/'],
'actions': ['list']
}
}
中间件校验权限:
permission_dict=request.session.get("permission_dict")
for item in permission_dict.values():
urls=item['urls']
for reg in urls:
reg="^%s$"%reg
ret=re.match(reg,current_path)
if ret:
print("actions",item['actions'])
request.actions=item['actions']
return None
return HttpResponse("没有访问权限!")
菜单权限
# 注册菜单权限
permissions = user.roles.all().values("permissions__url","permissions__action","permissions__group__title").distinct()
print("permissions",permissions)
menu_permission_list=[]
for item in permissions:
if item["permissions__action"]=="list":
menu_permission_list.append((item["permissions__url"],item["permissions__group__title"]))
print(menu_permission_list)
request.session["menu_permission_list"]=menu_permission_list
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。