前后端分离进行权限管理之后端生成菜单和权限信息(二)

一、初始化菜单、权限信息

在进行用户名和密码验证成功后就进行权限和菜单的初始化,生成该用户的菜单和权限数据。

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

原文地址:https://www.cnblogs.com/shenjianping/p/11448427.html

时间: 2024-10-13 17:55:34

前后端分离进行权限管理之后端生成菜单和权限信息(二)的相关文章

前后端分离实践:基于vue实现网站前台的权限管理

Javascript做为当下的热门语言,用途很广泛,从前端到后端处处可见其存在,该技术如今在我们项目内部也大量使用来开发诸如CMS系统以及其他其他一些数据分析系统的前端页面,为此个人非常感兴趣并将其作为帽子卡的扩展内容来进行课余学习. Javascript框架鳞次栉比,但基本原理大致相同,因此选用国内人开发的vue.js进行一个初步的尝试.学习vue.js也一周多的时间了,说起vue的主要用法,无外乎Declarative Rendering.Component System.Client-si

springboot配置shiro权限管理,网搜搜采集网站权限控制代码

import outshine.shiro.authc.AccountSubjectFactory; import outshine.shiro.filter.AuthenticatedFilter; import outshine.shiro.realm.AccountRealm; import org.apache.shiro.cache.CacheManager; import org.apache.shiro.cache.ehcache.EhCacheManager; import or

Linux权限管理总结(1)--基础权限

玩Linux的人都知道,Linux的安全性要比Windows高很多,而这主要是因为Linux中的安全权限机制,Linux中的用户和文件是组成系统的重点,而Linux的主要哲学思想是一切皆文件.Linux中的用户有用户的权限,分为普通用户和超级用户.文件有文件的权限,分别为读写执行权限.因为Linux中一切皆文件,对文件的操作就可以直接的操作系统,很多Linux高级服务器是没有图形界面的,都是对文件来直接操作来控制服务器,对文件的操作要通过用户来执行,而普通用户和超级用户的执行权限是不同的. 1.

Linux权限管理总结(2)--特殊权限

1.特殊权限facl(访问控制列表支持) 标准Linux文件系统(ext2/3/4)支持使用POSIX ACL设置多个复杂文件权限,   前提是文件系统是使用acl选项挂载的. 在Red Hat Enterprise Linux中,如果通过ls -l显示的权限字符串的最后一个字符是+,则文件或目录设置了ACL.  getfacl file用于显示文件的ACL u:willis:rw--#适用于用户willis u:500:---#适用于UID为500的用户 u::rwx#适用于file文件的拥有

权限管理之获取用户菜单信息

exclude(p__menu__isnull=True)  非空 原文地址:https://www.cnblogs.com/jintian/p/11255281.html

Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)

Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享)  点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJKN-MzscalsJKRoL5w 提取码:88hj 免费分享,如若链接失效请加群 其它资源在群里,私聊管理员即可免费领取:群——517432778,点击加群,或扫描二维码 免费课程资料领取目录:  Python Flask构建微信小程序订餐系统 Python分布式爬虫必学框架Scrapy打造搜索引擎

.NET Core前后端分离快速开发框架(Core.3.0+AntdVue)

.NET Core前后端分离快速开发框架(Core.3.0+AntdVue) 目录 引言 简介 环境搭建 开发环境要求 基础数据库构建 数据库设计规范 运行 使用教程 全局配置 快速开发 管理员登录 系统用户管理 系统角色管理 权限管理 接口秘钥管理 系统日志 单库事务 跨库事务 读写分离分库分表 常见疑问 如何进行联表查询 如何切换数据库类型 如何使用多个数据库 引言 时间真快,转眼今年又要过去了.回想今年,依次开源发布了Colder.Fx.Net.AdminLTE(254Star).Cold

一个简单粗暴的前后端分离方案

项目背景 刚刚参加完一个项目,背景:后端是用java,后端服务已经开发的差不多了,现在要通过web的方式对外提供服务,也就是B/S架构.后端专注做业务逻辑,不想在后端做页面渲染的事情,只向前端提供数据接口.于是协商后打算将前后端完全分离,页面上的所有数据都通过ajax向后端取,页面渲染的事情完全由前端来做.另外还有一个紧急的情况,项目要紧急上线,整个web站点的开发时间只有两周,两周啊!于是在这样的背景下,决定开始一次前后端完全分离的尝试. 之前开发都是同步渲染和异步渲染混搭的,有些东西可以有后

前后端分离及React的一些研究

前言 在对英才网企业线前端不断的完善过程中,我们尝试进行了前后端分离,引入Node环境.以及在使用React的过程中,自行开发DOM渲染框架,解决React兼容低版本IE的问题,在这个过程中,我们有了一些经验和体会,希望本文对您有所帮助. 为什么前后端分离 原有架构下,后端系统基于Java语言实现,通过Velocity模板实现服务器端渲染,前端同学维护静态资源,在维护页面状态时,还需要模板和脚本互传参数,模板中还会有很多UI逻辑,等等,前后端耦合很深,这种模式下开发效率非常低,联调成本非常高,同