前后端分離進行權限管理之后端生成菜單和權限信息(二)


一、初始化菜單、權限信息

在進行用戶名和密碼驗證成功后就進行權限和菜單的初始化,生成該用戶的菜單和權限數據。

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
InitPermission

其中菜單信息生成下述形式:

{
    {
      '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}}))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM