
######## 权限 ########
#用户登录成功后
1. setting 权限配置
2. 获取角色对应的所有权限
- permission_list = user.roles.values('permissions__id', 'permissions__caption', 'permissions__url','permissions__menu_id').distinct()
3. 获取权限列表
- permission_url_list = []
获取挂靠在菜单上权限列表
- permission_menu_list = []
4. 权限写入session
5. 菜单写入session
- 所有的菜单列表
- 挂靠在菜单上权限列表
#中间件
import re
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
from django.utils.safestring import mark_safe
class RbacMiddleware(MiddlewareMixin):
def process_request(self, request, *args, **kwargs):
"""
检查用户是否具有权限访问当前URL
:param request:
:param args:
:param kwargs:
:return:
"""
"""跳过无需权限访问的URL"""
for pattern in settings.RBAC_NO_AUTH_URL:
if re.match(pattern, request.path_info):
return None
"""获取当前用户session中的权限信息"""
permission_url_list = request.session.get(settings.RBAC_PERMISSION_URL_SESSION_KEY)
if not permission_url_list:
return HttpResponse(settings.RBAC_PERMISSION_MSG)
"""当前URL和session中的权限进行匹配"""
flag = False
for url in permission_url_list:
pattern = settings.RBAC_MATCH_PARTTERN.format(url)
if re.match(pattern, request.path_info):
flag = True
break
if not flag:
if settings.DEBUG:
return HttpResponse("无权访问,你的权限有:<br/>" + mark_safe("<br/>".join(permission_url_list)))
else:
return HttpResponse(settings.RBAC_PERMISSION_MSG)
用户登录,通过用户找到角色,通过角色找到这个用户的所有权限(注意权限去重),会生成两种数据格式:
- 权限:
ret = {
用户组1:{
"code":["list","add","del","edit"],
"url":[
"/userinfo/",
"/userinfo/add/",
"/userinfo/del/(d+)/",
"/userinfo/edit/(d+)/",
]
},
用户组2:{
},
}
- 菜单:
- 循环权限列表,如果不是菜单,继续循环。
- 获取菜单id,菜单标题,权限名称,权限url,active=False
menu_list = [
{'menu_id':1, 'menu_title':'菜单一','title':'用户列表','url':'/userinfo/','active':False},
{'menu_id':1, 'menu_title':'菜单一','title':'订单列表','url':'/order/'.'active':False},
{'menu_id':2, 'menu_title':'菜单二','title':'xxx列表','url':'/xxx/','active':False},
{'menu_id':2, 'menu_title':'菜单二','title':'iii列表','url':'/uuu/','active':False},
]
- 循环数据结构:
- 如果当前url和循环匹配,设置active=True
ret = {
1: {
'menu_id':1,
'menu_title':'菜单一',
'active':'True',
'children': [
{'title':'用户列表','url':'/userinfo/','active':True},
]
},
}
权限,首先运行中间件:
- 获取用户访问的url
- API白名单 循环配置文件的的白名单,和当前访问的url正则匹配,如果匹配成功,返回None,执行视图,不再执行中间件下的代码。
- 获取session中的权限,如果获取不到,证明没有登录,返回登录页面。
- 循环权限字典,判断当前url是否在ret[用户组]["url"]中
- 如果在,将code_list赋值给request,供前端控制 增加 编辑 删除
- 如果不在,返回无权限。
菜单
为什么会有用户组?
用户在根据当前url和session中的对比时,如果url匹配则获取code,供前端使用。
为了区分哪些url的各种code属于哪一类
用户组1:{
"code":["list","add","del","edit"],
"url":[
"/userinfo/",
"/userinfo/add/",
"/userinfo/del/(d+)/",
"/userinfo/edit/(d+)/",
]
code的作用?
供前端显示增加,删除,编辑。
为什么有菜单?
一个组下面的url的太少