zoukankan      html  css  js  c++  java
  • 权限组件之rbac

    rbac:基于角色的权限访问控制(Role-Based Access Control)。

    rbac的主要流程:给每个角色赋予不同的权限,是这个角色的员工都有这个角色的所有权限。一个角色可以有多个人员担任,一个员工可以担任多个角色(比如部门经理、业务员等)。当员工成功登陆系统时,系统需要获取这个员工的多有权限,并放到一个列表里面。然后员工在访问每个权限url时,系统需要进行判断该员工有没有这个权限进行这项操作。如何判断?就是循环这个员工的所有权限,看有没有对应的权限。这里用到了re模块里面的match方法。

    如下代码:

    # 需要先登陆,拿到该员工的权限列表并去重
    def
    login(request): if request.method=="GET": return render(request,"login.html") else: user=request.POST.get("user") pwd=request.POST.get("pwd") user=UserInfo.objects.filter(name=user,pwd=pwd).first() if user: # 验证成功之后做什么? request.session["user_id"]=user.pk # 设置session # 当前登录用户的所有权限, distinct()是去掉重复的权限 permission_info=user.roles.all().values("permissions__url","permissions__title").distinct() temp=[] # 该员工的全部权限url列表 for i in permission_info: temp.append(i["permissions__url"]) request.session["permission_list"]=temp # {"user_id":1,"permission_list":['/users/','/orders/']} return HttpResponse("登录成功!") else: return redirect("/login/")

     登陆成功之后,判断查看用户操作权限

    from django.shortcuts import HttpResponse
    
    def users(request):
        # //users/
        current_path = request.path_info  # 拿到访问的路径
        permission_list = request.session.get("permission_list")  # 取session,从session表里面取到这个员工的所有权限 ['/order/', '/users/']
    if not permission_list: # 用户没有登陆,取不到权限列表
    return HttpResponse("login.html") # /users/edit/3 为什么要用正则,因为/users/edit/3 与/users/edit/(/d+)不能直接匹配 import re flag = False # 加上标志位 for permission_url in permission_list: ret = re.match(permission_url, current_path) # 用正则去匹配具体的路径,成功则返回对象, 否则返回None if ret: # 如果返回对象 flag = True break if not flag: return HttpResponse("没有访问权限") return HttpResponse("用户列表") # 有权限

     接下来通过中间件来实现这个功能

    再创建一个应用名字叫做rbac(当然也可以放到同一个应用里面),这个应用里面创建一个包service,包里创建一个名字为permission_li.py的文件。

    from django.utils.deprecation import MiddlewareMixin
    
    from django.shortcuts import  redirect,HttpResponse,render
    
    class M1(MiddlewareMixin):
        def process_request(self,request):
            # //users/
            current_path = request.path_info  # 拿到访问的路径
            permission_list = request.session.get("permission_list")  # 从session表里面取到这个员工的所有权限 ['/order/', '/users/']
            # /users/edit/3  为什么要用正则,因为/users/edit/3 与/users/edit/(/d+)不能直接匹配
            import re
            flag = False  # 加上标志位
            for permission_url in permission_list:
                ret = re.match(permission_url, current_path)  # 用正则去匹配具体的路径,成功则返回对象, 否则返回None
                if ret:  # 如果返回对象
                    flag = True
                    break
            if not flag:
                return HttpResponse("没有访问权限")

    settings.py里面

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'rbac.service.permission_li.M1',  # 加在这里
    ]

    接下来的问题就是,加上中间件之后,登陆页面也没有权限访问了。

    我们添加白名单,登陆、注册和admin页面加里即可。

    from django.utils.deprecation import MiddlewareMixin
    
    from django.shortcuts import  redirect,HttpResponse,render
    
    class M1(MiddlewareMixin):
        def process_request(self,request):
            pass
    
            #/admin/login/?next=/admin/
            current_path = request.path_info
    
            valid_url_menu=["/login/","/reg/","/admin/.*"]
            import re
            for valid_url in valid_url_menu:
                ret=re.match(valid_url,current_path)
                if ret:
                    return None
    
            permission_list = request.session.get("permission_list")
            if not permission_list:
                return redirect("/login/")
            # /users/edit/3
            import re
            flag = False
            for permission_url in permission_list:
                ret = re.match(permission_url, current_path)
                if ret:
                    flag = True
                    break
            if not flag:
                return HttpResponse("没有权限")
  • 相关阅读:
    C# winform 使用FastReport.Net自动打印一维码条码和二维码的解决方法
    C# winform 使用rdlc打印小票其中包含动态显示多条形码的解决方法
    我学习的LIS系统业务
    C# DataTable DataSet DataRow 转实体类集合,实体类和实体类集合转成DataTable 扩展方法分享
    我的自动化设备上位机软件开发设计(一)
    打开操作系统数据执行保护,关闭操作系统数据执行保护
    visualstudio2019 的报表技术rdlc在windows10上出现乱码的问题解决方法
    我带旅游ERP管理系统开发的经历
    C# web程序,winform程序,控制台程序配置log4net,使用log4net
    freemodbus modbus TCP 学习笔记
  • 原文地址:https://www.cnblogs.com/aaronthon/p/9463649.html
Copyright © 2011-2022 走看看