前后端分离进行权限管理之后端生成菜单和权限信息
Posted shenjianping
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前后端分离进行权限管理之后端生成菜单和权限信息相关的知识,希望对你有一定的参考价值。
一、初始化菜单、权限信息
在进行用户名和密码验证成功后就进行权限和菜单的初始化,生成该用户的菜单和权限数据。
class LoginView(APIView): authentication_classes = [] # 登陆页面免认证,其余的已经全局配置 def post(self, request, *args, **kwargs): ret = "data": , "meta": "code": 2001, "message": "用户名或密码错误" user_obj = json.loads(str(request._request.body, encoding=‘utf8‘)) username = user_obj.get(‘username‘) password = user_obj.get(‘password‘) if username and password: obj = UserInfo.objects.filter( username=username, password=password).first() if obj: #初始化权限、菜单信息 InitPermission(request,obj).init_menus_dict() InitPermission(request,obj).init_permissions_dict() # 生成token值 # token=str(uuid.uuid4()) #uuid生成token token = get_md5(username) ret["data"]["username"] = username ret["data"]["password"] = password ret["data"]["token"] = token # ret["data"]["permission_session_id"] = settings.PERMISSION_SESSION_KEY # ret["data"]["menu_session_id"] = settings.MENU_SESSION_KEY ret["meta"]["code"] = 2000 ret["meta"]["message"] = "登陆成功" else: pass else: pass return HttpResponse(json.dumps(ret, ensure_ascii=False))
二、生成菜单、权限信息
通过将用户名传入Initpermission类中进行处理
from rbac import models from django.conf import settings from crm.utils.session import SessionStore import json class InitPermission(object): def __init__(self, request, user): self.request = request self.user = user self.permissions_dict = self.menus_dict = def init_data(self): """ 从数据库中获取权限信息以及用户信息 :return: """ self.permissions_queryset = self.user.roles.filter(permissions__url__isnull=False).values( ‘permissions__id‘, ‘permissions__url‘, ‘permissions__title‘, ‘permissions__parent_id‘, ‘permissions__action__code‘, ‘permissions__menu_id‘, ‘permissions__menu__title‘, ‘permissions__menu__icon‘, ‘permissions__menu__position‘ ).distinct() return self.permissions_queryset def init_permissions_dict(self): """ 初始化权限,获取当前用户权限并添加到session中 将当前用户权限信息转换为以下格式,并将其添加到Session中 ‘/index.html‘: [‘GET‘,‘POST‘,‘DEL‘,‘EDIT], ‘/detail-(\d+).html‘: [‘GET‘,‘POST‘,‘DEL‘,‘EDIT], :return: """ for row in self.init_data(): if row["permissions__url"] in self.permissions_dict: self.permissions_dict[row["permissions__url"]].append(row["permissions__action__code"]) else: self.permissions_dict[row["permissions__url"]] = [row["permissions__action__code"], ] print(‘init‘,self.permissions_dict) #将权限信息存入redis,后续中间件中去除进行验证 SessionStore().set_session(settings.PERMISSION_SESSION_KEY,self.permissions_dict) return self.permissions_dict def init_menus_dict(self): """ self.menus_dict= 1: title:‘客户管理‘,icon:‘fa fa-coffe‘,children:[ ‘id‘:1,‘url‘:‘/customer/list/‘,‘title‘:‘客户列表‘ ... ] :return: """ for row in self.init_data(): menu_id = row["permissions__menu_id"] if not menu_id: continue if menu_id not in self.menus_dict: self.menus_dict[row["permissions__menu__position"]] = "id":row["permissions__menu_id"], "title": row["permissions__menu__title"], "icon": row["permissions__menu__icon"], "children": [ ‘id‘: row[‘permissions__id‘], ‘title‘: row[‘permissions__title‘], ‘url‘: row[‘permissions__url‘] ] else: self.menus_dict[row["permissions__menu__position"]]["children"].append( ‘id‘: row[‘permissions__id‘], ‘title‘: row[‘permissions__title‘], ‘url‘: row[‘permissions__url‘] ) return self.menus_dict
其中菜单信息生成下述形式:
‘title‘: ‘用户管理‘, ‘icon‘: ‘el-icon-location‘, ‘id‘: 1, ‘children‘: [‘title‘: ‘用户列表‘, ‘url‘: ‘/crm/user‘, ‘id‘: 1, ‘title‘: ‘部门列表‘, ‘url‘: ‘/crm/dept‘, ‘id‘: 11 ] , ‘title‘: ‘权限管理‘, ‘icon‘: ‘el-icon-s-check‘, ‘id‘: 2, ‘children‘: [‘title‘: ‘权限列表‘, ‘url‘: ‘/rbac/rights/list‘, ‘id‘: 2, ‘title‘: ‘角色列表‘, ‘url‘: ‘/rbac/roles‘, ‘id‘: 7, ‘title‘: ‘菜单列表‘, ‘url‘: ‘/crm/menus‘, ‘id‘: 12 ]
权限信息生成以下形式:
‘/crm/dept‘: [‘get‘], ‘/crm/menus‘: [‘get‘], ‘/rbac/roles‘: [‘get‘], ‘/rbac/roles/(?P<roleId>\\d+)/permission$‘: [‘put‘], ‘/rbac/rights/list‘: [‘get‘], ‘/rbac/roles/(?P<roleId>\\d+)/permission/(?P<permissionId>\\d+)$‘: [‘delete‘], ‘/crm/user‘: [‘get‘, ‘post‘]
上面就是某一个用户所拥有的菜单以及权限信息。
三、中间件进行权限校验
from django.utils.deprecation import MiddlewareMixin from django.conf import settings import re from django.shortcuts import HttpResponse import json from crm.utils.session import SessionStore class RbacMiddleware(MiddlewareMixin): def process_request(self,request,*args,**kwargs): """跳过无需权限访问的URL""" # permission_dict = request.session.get(settings.RBAC_PERMISSION_SESSION_KEY) print(‘process_request‘,request.path_info) for pattern in settings.RBAC_NO_AUTH_URL: if re.match(pattern, request.path_info): return None #从redis中获取permission_dict,是bytes类型 permission_bytes = SessionStore().get_session(settings.PERMISSION_SESSION_KEY) permission_dict = eval(permission_bytes)
if not permission_dict: return HttpResponse(json.dumps("data": , "meta": "message": "无权限访问", "code": 2002)) #请求url与redis中存储的权限进行匹配 """ ‘/rights‘: [‘get‘], ‘/user‘: [‘get‘, ‘post‘], ‘/roles‘: [‘get‘] """ flag = False for pattern,code_list in permission_dict.items(): print(‘par,code...‘,pattern,request.path_info) upper_code_list=[item.upper() for item in code_list] request_permission_code = request.method if re.match(pattern,request.path_info): print(request_permission_code) print(upper_code_list) if request_permission_code in upper_code_list: permission_code_list = upper_code_list
#将用户角色拥有的请求方式存储起来,传给前端进行按钮权限的验证 SessionStore().set_session(settings.PERMISSION_CODE_LIST_KEY,permission_code_list) flag = True breakif not flag: return HttpResponse(json.dumps("data": , "meta": "message": "rbac无权限访问", "code": 2002))
以上是关于前后端分离进行权限管理之后端生成菜单和权限信息的主要内容,如果未能解决你的问题,请参考以下文章