权限

######## 权限 ########

#用户登录成功后 

	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的太少

  

  

原文地址:https://www.cnblogs.com/golangav/p/7568114.html