zoukankan      html  css  js  c++  java
  • Title

    一、把rbac组件拷贝到你的Django项目中

    二、settings里注册一下app名字

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 'web.apps.WebConfig',
        'web',
        'rbac',
    ]

    三、python manage.py makemigrations 和 python manage.py migrate生成数据库表单

    四、在settings里注册一下中间件,用来验证用户权限

    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.middleware.rbac.RbacMiddleware'
    ]

    五、在settings里最下方配置权限相关的信息

    # ############################## RBAC权限相关配置开始 ##############################
    # # 无需权限控制的URL(白名单)
    RBAC_NO_AUTH_URL = [
        '/login.html',
        '/index.html',
        '/register.html',
        '/admin.*',
        '/rbac.*',
    ]
    
    # session中保存权限信息的Key名
    RBAC_PERMISSION_SESSION_KEY = "rbac_permission_session_key"
    
    # Http请求中传入的参数,根据其获取GET、POST、EDIT等检测用户是否具有相应权限
    # 例如:
    #       http://www.example.com?md=get   表示获取
    #       http://www.example.com?md=post  表示添加
    #       http://www.example.com?md=del   表示删除
    RBAC_QUERY_KEY = "md"
    RBAC_DEFAULT_QUERY_VALUE = "look"
    
    # 无权访问时,页面提示信息
    RBAC_PERMISSION_MSG = "无权限访问"
    
    # Session中保存菜单和权限信息的Key
    RBAC_MENU_PERMISSION_SESSION_KEY = "rbac_menu_permission_session_key"
    RBAC_MENU_KEY = "rbac_menu_key"
    RBAC_MENU_PERMISSION_KEY = "rbac_menu_permission_key"
    
    # 菜单主题
    RBAC_THEME = "default"
    # ############################## RBAC权限相关配置结束 ##############################
    

      

    六、登录的页面login.html

    在你应用的app的models.py中创建UserInfo一对一关联rabc里的User表

    from django.db import models
    from rbac.models import User as RbacUser
    class UserInfo(models.Model):
        nickname = models.CharField(max_length=16)
        user = models.OneToOneField(RbacUser)
    models.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/login.html" method="POST">
        {% csrf_token %}
        <div><input type="text" name="username" id=""></div>
        <div><input type="password" name="passwd" id=""></div>
        <div><input type="submit" value="提交"></div>
    </form>
    </body>
    </html>
    login.html
    from django.conf.urls import url
    from django.contrib import admin
    from web import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login.html', views.login),
        url(r'^index.html', views.index),
    ]
    url配置
    from django.shortcuts import render,HttpResponse,redirect
    from web import models
    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        else:
            u = request.GET.get('username')
            p = request.GET.get('passwd')
            # 跨表到rbac的用户表里拿用户名和密码
            obj = models.UserInfo.objects.filter(user__username=u,user__password=p).first()
            # obj.id 是UserInfo表里的自增id
            # obj.nickname
            # obj.user_id 是rbac的User表里的用户id
            # obj.id和obj.user_id不一样
            if obj:# 表示用户存在,登录成功
             # 获取当前用户权限
             # 获取当前用用户菜单
             # 去配置文件里拿相应的key,写入session中
             # 在rbac组件的service.py中的initial_permission已经把上面的步骤都做好了,只需要传入参数request和obj.user_id
             from rbac.service import initial_permission
             initial_permission(request,obj.user_id)
    
             request.session['user_info'] = {'username':u,'nickname':obj.nickname,'nid':obj.id} # 添加一些自己的信息
    
             return redirect('/index.html')
            else:
                return render(request,'login.html')

    中间件的函数

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import re
    from django.conf import settings
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    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_dict = request.session.get(settings.RBAC_PERMISSION_SESSION_KEY)
            if not permission_dict:
                # settings.RBAC_PERMISSION_MSG 返回错误信息:'无权限访问'
                return HttpResponse(settings.RBAC_PERMISSION_MSG)
    
            """当前URL和session中的权限进行匹配"""
    
            flag = False
            for pattern, code_list in permission_dict.items():
                upper_code_list = [item.upper() for item in code_list]  # 把方法列表都变成大写
                if re.match(pattern, request.path_info):                # 匹配可以访问的url和当前URL
                    # settings.RBAC_QUERY_KEY是'md' ; 异常时默认拿到settings.RBAC_DEFAULT_QUERY_VALUE 即'GET'
                    request_permission_code = request.GET.get(settings.RBAC_QUERY_KEY, settings.RBAC_DEFAULT_QUERY_VALUE).upper()
                    if request_permission_code in upper_code_list:
                        request.permission_code = request_permission_code  # 当前的方法权限加入request
                        request.permission_code_list = upper_code_list     # 当前的方法权限列表加入request中
                        flag = True
                        break
    
            if not flag:
                # settings.RBAC_PERMISSION_MSG 返回错误信息:'无权限访问'
                return HttpResponse(settings.RBAC_PERMISSION_MSG)
    

      

    在用户验证登录成功后跳转到index函数和index.html页面

    CBV函数的写法

    def index(request):
        # permission_code是在中间件的代码里获取的当前登录用户所请求的权限方法
        # request.permission_code 当前登录用户所请求的权限
        # request.permission_code_list 当前登录用户所具有的权限方法
        if request.permission_code == 'GET':
            # 查看权限
            pass
        elif request.permission_code == 'POST':
            # 增加权限
            pass
        elif request.permission_code == 'DEL':
            # 删除权限
            pass
        elif request.permission_code == 'EDIT':
            # 编辑权限
            pass
        return render(request,'index.html')

    FBV中的写法

    from django.views import View
    from rbac.cbv.views import RbacView
    # 用于Django视图CBV模式时,根据请求地址后携带md对应的值执行相应的方法,如:
    class MyView(RbacView, View):
        def get(request, *args, **kwargs):
            pass
    
        def delete(request, *args, **kwargs):
            pass
    
        def put(request, *args, **kwargs):
            pass
    
        def post(request, *args, **kwargs):
            pass
    
    # MyView类中方法的名称取决于数据库action表code字段的值。PS:此处方法为小写

    在app的models中添加报障表

    from django.db import models
    from rbac.models import User as RbacUser
    class UserInfo(models.Model):
        nickname = models.CharField(max_length=16)
        user = models.OneToOneField(RbacUser)
    
    class Order(models.Model):
        nid = models.IntegerField(primary_key=True)
        """
        报障单
        """
        title = models.CharField(verbose_name='报障标题',max_length=64)
        detail = models.TextField(verbose_name='故障详细')
        create_user = models.ForeignKey(UserInfo,related_name='cre')
        create_time = models.DateTimeField()
        status_choice = (
            (1,'未处理'),
            (2,'处理中'),
            (3,'已处理'),
        )
        status = models.IntegerField(choices=status_choice,default=1)
        processor = models.ForeignKey(UserInfo,related_name='pro',null=True,blank=True)
        solution = models.TextField(null=True,blank=True)
        processor_time = models.DateTimeField()
    View Code

    然后python manage.py makemigrations 和 python manage.py migrate 生成一下,

    报障管理

      普通员工

        提报障单    trouble.html

          创建

          修改

          删除

          查看列表

          查看详细

      运维人员

        解决报障单    trouble-kill.html

      总监

        提报障单

        解决报障单

        查看报表    report.html

    先在admin里注册一下表单

    from django.contrib import admin
    from web import models
    
    admin.site.register(models.UserInfo)
    admin.site.register(models.Order)
    

      

    用admin给rabc的User表添加数据

    给Role表里添加三个角色:总监、运维、员工

    然后User2Role分配一下用户是什么角色(一个用户可以有多个角色)

    菜单添加一个保障管理即可

    permission里添加权限名称:报障,URL正则:/trouble.html,所属菜单:报障管理

      权限名称:解决报障,URL正则:/trouble-kill.html,所属菜单:报障管理

      权限名称:查看报表,URL正则:/report.html,所属菜单:报障管理

    action表中创建几个方法 post   del    edit    look    detail

    permission2action2role 分配权限 员工拥有报障单的所有方法权限    运维拥有解决报障单的所有方法权限

     七、在index.html中导入自定义的simple_tag

    {% load rbac %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            body{
                margin: 0;
            }
            .pd-header{
                height: 48px;
                background-color: brown;
            }
            .pd-menu{
                float: left;
                width: 20%;
            }
            .pd-content{
                float: left;
                width: 80%;
            }
            {% rbac_css %}
        </style>
    </head>
    <body>
        <div class="pd-header"></div>
        <div class="pd-body">
            <div class="pd-menu">{% rbac_menu request %}</div>
            <div class="pd-content">Welcome : {{ request.session.user_info.nickname }}</div>
        </div>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            {% rbac_js %}
        </script>
    </body>
    </html>
    index.html

    创建母模layout.html

    {% load rbac %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            body{
                margin: 0;
            }
            .pd-header{
                height: 48px;
                background-color: brown;
            }
            .pd-menu{
                float: left;
                width: 20%;
            }
            .pd-content{
                float: left;
                width: 80%;
            }
            {% rbac_css %}
        </style>
        {% block css %}{% endblock %}
    </head>
    <body>
        <div class="pd-header"></div>
        <div class="pd-body">
            <div class="pd-menu">{% rbac_menu request %}</div>
            <div class="pd-content">{% block content %}{% endblock %}</div>
        </div>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            {% rbac_js %}
        </script>
    {% block js %}{% endblock %}
    </body>
    </html>
    layout.html

    index.html继承模板

    {% extends 'layout.html' %}
        {% block content %}
            Welcome : {{ request.session.user_info.nickname }}
        {% endblock %}
    index.html

     request.permission_code_list 传到前端显示用户所具有的权限功能按钮

    报障页面

    {% extends 'layout.html' %}
        {% block content %}
            {# 当用户有POST权限方法在他的权限方法列表permission_code_list里时才显示添加 #}
            <div>
                {% if 'POST' in request.permission_code_list %}
                    <a href="/trouble.html?md=post">添加</a>
                {% endif %}
            </div>
           <div>
                <table border="1px">
                    {% for row in trouble_list %}
                        <tr>
                            <td>{{ row.title }}</td> {# 报障的标题 #}
                            <td>{{ row.status }}</td> {# 报障的状态 数字 #}
                            <td>
                                {% if 'EDIT' in request.permission_code_list %}
                                    <a href="/trouble.html?md=edit&nid={{ row.nid }}">编辑</a>
                                {% endif %}
                            </td>
                            <td>
                                {% if 'DEL' in request.permission_code_list %}
                                    <a href="/trouble.html?md=del&nid={{ row.nid }}">删除</a>
                                {% endif %}
                            </td>
                            <td>
                                {% if 'DETAIL' in request.permission_code_list %}
                                    <a href="/trouble.html?md=detail&nid={{ row.nid }}">查看详细</a>
                                {% endif %}
                            </td>
                        </tr>
                    {% endfor %}
                </table>
           </div>
        {% endblock %}
    trouble.html

    后端处理的trouble函数

    def trouble(request):
        # 请求方法request.permission_code 是LOOK时
        if request.permission_code == 'LOOK':
            # 获取报障表中登录用户所自己提出的报障列表
            trouble_list = models.Order.objects.filter(create_user_id=request.session['user_info']['nid'])
            return render(request,'trouble.html',{'trouble_list':trouble_list})
        # 请求方法request.permission_code 是DEL时
        elif request.permission_code == 'DEL':
            nid = request.GET.get('nid')  # 获取用户的创建的报障单中某一条的具体的ID,然后进行删除
            models.Order.objects.filter(create_user_id=request.session['user_info']['nid'],nid=nid).delete()
            return redirect('/trouble.html')
        # 想要提交报障单
        elif request.permission_code == 'POST':
            if request.method == 'GET':
                return render(request,'trouble-add.html')  # 给他返回一个填写报障单的页面
            else:
                # 获取填写的标题、内容等,然后写入Order表中
                title = request.POST.get('title')
                content = request.POST.get('content')
                models.Order.objects.create(title=title,detail=content,create_user_id=request.session['user_info']['nid'])
                return redirect('/trouble.html')
        # 想要进行编辑
        elif request.permission_code == 'EDIT':
            if request.method == 'GET':
                # 在数据库中查到要编辑的那条信息,返回给前端渲染出来
                nid = request.GET.get('nid')
                obj = models.Order.objects.filter(create_user_id=request.session['user_info']['nid'],nid=nid).first()
                return render(request,'trouble-edit.html',{'obj':obj,'nid':nid})
            else:
                # url中拿到文章nid 在POST中拿到更改的信息
                nid = request.GET.get('nid')
                new_title = request.POST.get('new_title')
                new_content = request.POST.get('new_content')
                models.Order.objects.filter(create_user_id=request.session['user_info']['nid'],nid=nid).update(title=new_title,detail=new_content)
                return redirect('/trouble.html')
        # 要查看具体的报障信息的话
        elif request.permission_code == 'DETAIL':
            # url中拿到文章nid 查到具体对象 返回前端渲染出来
            nid = request.GET.get('nid')
            obj = models.Order.objects.filter(create_user_id=request.session['user_info']['nid'], nid=nid).first()
            return render(request,'trouble-detail.html',{'obj':obj})
    def trouble(request):

    --------------------------------------------------------------------------------------------------------------------------------------------------

    重新再记录一边更详细的过程

    一、项目需求分析

      对登录的用户进行权限管理,包括了给用户分配权限( 即用户可以看到自己可以操作的方法和URL链接绑定起来 ),回收权限( 员工离职后要把他的相应权限和个人信息删除掉,保证员工不能干坏事)。

     二、表结构关系

     三、计划

      我们打算创建这样一个组件,在settings中的中间件注册一个类,这个类用来做以下内容:

      1. 跳过无需权限访问的URL,我们可以在配置文件中写一个白名单,

    # 无需权限控制的URL(白名单)
    RBAC_NO_AUTH_URL = [
        '/login.html',
        '/index.html',
        '/register.html',
        '/admin.*',
        '/rbac.*',
    ]
    View Code

      如果当前访问的URL(request.path_info)在白名单中则直接跳过,

    import re
    from django.conf import settings
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class RbacMiddleware(MiddlewareMixin):
        def process_request(self, request, *args, **kwargs):
            """
            检查用户是否具有权限访问当前URL
            :param request: 
            :param args: 
            :param kwargs: 
            :return: 
            """
            """跳过无需权限访问的URL"""
            print(request.path_info)
            for pattern in settings.RBAC_NO_AUTH_URL:
                if re.match(pattern, request.path_info):
                    return None
    rbac.py

      不用检验用户的权限了,因为你要给用户看到网站的主页和登录注册界面啊,要是什么都限制了,那么用户连登录也登录不了了。

      2.获取当前用户session中的权限信息,假设用户是访问登录界面,则会跳过这个中间件,直接到登录界面,用户输入账号和密码后直接POST或者Ajax到后台的login函数验证,login函数根据发过来的用户名和密码去数据库的User表找,找到了,那么就把当前的用户的一些信息写入session中,还有把当前用户的拥有的方法和URL权限也写入session中,或者Form组件验证。

    from django.shortcuts import render,HttpResponse,redirect
    from django.shortcuts import render,HttpResponse,redirect
    from mysite import models
    from rbac import models as Rbacmodels
    def test(request):
        return HttpResponse('...')
    
    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        else:
            u = request.POST.get('username')
            p = request.POST.get('passwd')
            # 跨表到rbac的用户表里拿用户名和密码
            obj = models.UserInfo.objects.filter(user__username=u,user__password=p).first()
            # obj.id 是UserInfo表里的自增id
            # obj.nickname
            # obj.user_id 是rbac的User表里的用户id
            # obj.id和obj.user_id不一样
            if obj:# 表示用户存在,登录成功
                 # 获取当前用户权限
                 # 获取当前用用户菜单
                 # 去配置文件里拿相应的key,写入session中
                 # 在rbac组件的service.py中的initial_permission已经把上面的步骤都做好了,只需要传入参数request和obj.user_id
                 from rbac.service import initial_permission
                 initial_permission(request,obj.user_id)
    
                 request.session['user_info'] = {'username':u,'nickname':obj.nickname,'nid':obj.id} # 添加一些自己的信息
    
                 # return redirect('/index.html')
                 return render(request,'index.html',{'obj':obj})
            else:
                return render(request,'login.html')
    views.py

      其中把当前用户的拥有的方法和URL权限也写入session中时由于代码比较多于是封装在一个py文件的函数中,只需要传入request和用户ID即可。

      接下来详细讨论一下把权限信息写入session的步骤:

      我们给封装在service.py的initial_permission函数传入了请求信息request和用户的id,首先我们要做的就是初始化权限信息,

        1.根据用户id拿到用户对应的角色(一个用户可以扮演多个角色)

        2.通过 role__in=roles 拿到  URL&方法&角色  表 对应的数据并通过distinct()去重。拿到字典类型 类似这样子{'permission__url':'trouble_kill.html','action__code':'add'}

    p2a = models.Permission2Action2Role.objects.filter(role__in=roles).values('permission__url',"action__code").distinct()
    

        3.创建一个字典 user_permission_dict = {}

        4.遍历 p2a 拿到的多条数据对象,如果字典user_permission_dict 中没有 permission__url ,表明是第一次加入这个URL,对应的把它的具有的action方法加入以列表的形式作为该URL的value值,否则走else的时候就是user_permission_dict中已经有该URL了,但是传来了另一个action方法,比如user_permission_dict字典的形式为 { '/index.html': ['DEL'] } ,第二次传来的是{'permission__url':'/index.html','action__code':'POST'} 相同URL的时候走else然后把新的value值'POST'加入该URL对应的列表中,最后可能变成这样 { '/index.html': ['GET','POST','DEL','EDIT]}  该用户对应拥有的URL所拥有的action方法封装成一个字典,

        for item in p2a:
            if item['permission__url'] not in user_permission_dict:
                user_permission_dict[item['permission__url']] = [item['action__code'], ]
            else:
                user_permission_dict[item['permission__url']].append(item['action__code'])
    

        5.然后 request.session[settings.RBAC_PERMISSION_SESSION_KEY] = user_permission_dict 把用户的权限写入session中,其中user_permission_dict可能长下面这样:

    user_permission_dict={
                        '/index.html': ['GET','POST','DEL','EDIT],
                        '/detail-(d+).html': ['GET','POST','DEL','EDIT],
                        }
    View Code

        6.紧接着我们要初始化菜单信息了,首先把Menu表的 'id', 'caption', 'parent_id' 信息拿到,并转换为列表中包含多个字典的menu_list,通过跨表拿到权限id、权限的URL、权限的名称、权限挂载到的菜单id,外表包一层list列表,里边是一个个字典。

    menu_permission_list = list(models.Permission2Action2Role.objects.filter(role__in=roles,
                                                                            permission__menu__isnull=False).values(
            'permission_id',
            'permission__url',
            'permission__caption',
            'permission__menu_id').distinct())
    View Code

        7.紧接着我们就可以把菜单列表(传到前端页面显示菜单栏)和菜单权限列表写入session中了。

    request.session[settings.RBAC_MENU_PERMISSION_SESSION_KEY] = {
            settings.RBAC_MENU_KEY: menu_list,
            settings.RBAC_MENU_PERMISSION_KEY: menu_permission_list
        }
    View Code

           8.此时request.session已经有我们需要的信息大概封装了以下类似信息

    user_permission_dict={
                        '/index.html': ['GET','POST','DEL','EDIT],
                        '/detail-(d+).html': ['GET','POST','DEL','EDIT],
                        }
    request.session[settings.RBAC_PERMISSION_SESSION_KEY] = user_permission_dict
    
    menu_list = [
        {'id':1,'caption':'财务查询','parent_id':None},
        {'id':2,'caption':'报障单管理','parent_id':None},
    ]
    menu_permission_list = [
        {'permission_id':1,
         'permission__url':'trouble_kill.html',
         'permission__caption':'提交报障单',
         'permission__menu_id':2},
        {'...'}
    ]
    request.session[settings.RBAC_MENU_PERMISSION_SESSION_KEY] = {
            settings.RBAC_MENU_KEY: menu_list,
            settings.RBAC_MENU_PERMISSION_KEY: menu_permission_list
        }
    View Code

           9.详细的service.py代码如下,

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import re
    from django.conf import settings
    from . import models
    
    def initial_permission(request, user_id):
        """
        初始化权限,获取当前用户权限并添加到session中
        将当前用户权限信息转换为以下格式,并将其添加到Session中
            {
                '/index.html': ['GET','POST','DEL','EDIT],
                '/detail-(d+).html': ['GET','POST','DEL','EDIT],
            }
        
        :param request: 请求对象
        :param user_id: 当前用户id
        :return: 
        """
    
        """初始化权限信息"""
        roles = models.Role.objects.filter(users__user_id=user_id)
    
        p2a = models.Permission2Action2Role.objects.filter(role__in=roles).values('permission__url',
                                                                                  "action__code").distinct()
        user_permission_dict = {}
        for item in p2a:
            if item['permission__url'] in user_permission_dict:
                user_permission_dict[item['permission__url']].append(item['action__code'])
            else:
                user_permission_dict[item['permission__url']] = [item['action__code'], ]
    
        request.session[settings.RBAC_PERMISSION_SESSION_KEY] = user_permission_dict
    
        """初始化菜单信息,将菜单信息和权限信息添加到session中"""
        menu_list = list(models.Menu.objects.values('id', 'caption', 'parent_id'))
    
        menu_permission_list = list(models.Permission2Action2Role.objects.filter(role__in=roles,
                                                                            permission__menu__isnull=False).values(
            'permission_id',
            'permission__url',
            'permission__caption',
            'permission__menu_id').distinct())
        request.session[settings.RBAC_MENU_PERMISSION_SESSION_KEY] = {
            settings.RBAC_MENU_KEY: menu_list,
            settings.RBAC_MENU_PERMISSION_KEY: menu_permission_list
        }
    
    def fetch_permission_code(request, url):
        """
        根据URL获取该URL拥有的权限,如:["GET","POST"]
        :param request: 
        :param url: 
        :return: ["GET","POST"]
        """
        user_permission_dict = request.session.get(settings.RBAC_PERMISSION_SESSION_KEY)
        if not user_permission_dict:
            return []
        for pattern, code_list in user_permission_dict.items():
            if re.match(pattern, url):
                return code_list
        return []
    service.py

       如果request.session.get(settings.RBAC_PERMISSION_SESSION_KEY) 拿不到权限信息,则直接返回无权限访问的信息,如果拿到了,那么请看下面的第三步。

      3.当前URL和session中的权限进行匹配。

    flag = False
            for pattern, code_list in permission_dict.items():
                upper_code_list = [item.upper() for item in code_list]  # 把方法列表都变成大写  ['GET','POST','DEL','EDIT]
                if re.match(pattern, request.path_info):                # 匹配可以访问的url和当前URL
                    # settings.RBAC_QUERY_KEY是'md' ; 异常时默认拿到settings.RBAC_DEFAULT_QUERY_VALUE 即'GET'
                    request_permission_code = request.GET.get(settings.RBAC_QUERY_KEY, settings.RBAC_DEFAULT_QUERY_VALUE).upper()
                    if request_permission_code in upper_code_list:
                        request.permission_code = request_permission_code  # 当前的方法权限加入request
                        request.permission_code_list = upper_code_list     # 当前的方法权限列表加入request中
                        flag = True
                        break
    View Code

        1. 我们遍历写在session中的权限信息,数据类型可能是这样的。

    permission_dict={
           '/index.html': ['get','post','del','edit'],
           '/detail-(d+).html': ['get','post','del','edit],
    }
    

        2. 把URL赋值给 pattern,把方法列表赋值给 code_list ,

        3. upper_code_list = [item.upper() for item in code_list] # 把方法列表都变成大写 ['GET','POST','DEL','EDIT]

        4. 然后拿到当前的URL :request.path_info 通过正则匹配当前pattern值对应的URL看当前请求的url 和权限列表中是否匹配,不匹配则接着for循环找,匹配的话走5

        5. # settings.RBAC_QUERY_KEY是'md' ; 异常时默认拿到settings.RBAC_DEFAULT_QUERY_VALUE 即'GET' , request.GET.get() 拿到如URL中 md = ‘del’ 等的方法,出错则默认拿到 'GET' 方法。

    request_permission_code = request.GET.get(settings.RBAC_QUERY_KEY, settings.RBAC_DEFAULT_QUERY_VALUE).upper()
    

        6.如果检测到当前URL中md等于的某个方法在code_list中时,把request.permission_code = request_permission_code # 当前的方法权限加入request

        7. request.permission_code_list = upper_code_list # 当前的方法权限列表加入request中 ,然后结束循环。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import re
    from django.conf import settings
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
    class RbacMiddleware(MiddlewareMixin):
        def process_request(self, request, *args, **kwargs):
            """
            检查用户是否具有权限访问当前URL
            :param request: 
            :param args: 
            :param kwargs: 
            :return: 
            """
            """跳过无需权限访问的URL"""
            print(request.path_info)
            for pattern in settings.RBAC_NO_AUTH_URL:
                if re.match(pattern, request.path_info):
                    print(request.path_info,pattern)
                    return None
    
            """获取当前用户session中的权限信息"""
            permission_dict = request.session.get(settings.RBAC_PERMISSION_SESSION_KEY)
            if not permission_dict:
                # settings.RBAC_PERMISSION_MSG 返回错误信息:'无权限访问'
                return HttpResponse(settings.RBAC_PERMISSION_MSG)
    
            """当前URL和session中的权限进行匹配"""
    
            flag = False
            for pattern, code_list in permission_dict.items():
                upper_code_list = [item.upper() for item in code_list]  # 把方法列表都变成大写
                if re.match(pattern, request.path_info):                # 匹配可以访问的url和当前URL
                    # settings.RBAC_QUERY_KEY是'md' ; 异常时默认拿到settings.RBAC_DEFAULT_QUERY_VALUE 即'GET'
                    request_permission_code = request.GET.get(settings.RBAC_QUERY_KEY, settings.RBAC_DEFAULT_QUERY_VALUE).upper()
                    if request_permission_code in upper_code_list:
                        request.permission_code = request_permission_code  # 当前的方法权限加入request
                        request.permission_code_list = upper_code_list     # 当前的方法权限列表加入request中
                        flag = True
                        break
    
            if not flag:
                # settings.RBAC_PERMISSION_MSG 返回错误信息:'无权限访问'
                return HttpResponse(settings.RBAC_PERMISSION_MSG)
    rbac.py

       4.以上流程过后,那么证明了你是合法的用户和请求,那么你就可借接着跳转到你的页面了,做一些你可以被允许做的事情:

    def index(request):
        # permission_code是在中间件的代码里获取的当前登录用户所请求的权限方法
        # request.permission_code 当前登录用户所请求的权限
        # request.permission_code_list 当前登录用户所具有的权限方法
        if not request.session.get('user_info'):
            return redirect('/login.html')
    
        return render(request,'index.html')
        # if request.permission_code == 'GET':
        #     # 查看权限
        #     pass
        # elif request.permission_code == 'POST':
        #     # 增加权限
        #     pass
        # elif request.permission_code == 'DEL':
        #     # 删除权限
        #     pass
        # elif request.permission_code == 'EDIT':
        #     # 编辑权限
        #     pass
        # return render(request,'index.html')
    views.py

      待更新......

    
    
  • 相关阅读:
    使用 Anthem.NET 的经验小结
    使用 Anthem.NET 的常见回调(Callback)处理方式小结
    Anthem.NET 的回调流程图
    客户端调用服务器端方法——ASP.NET AJAX(Atlas)、Anthem.NET和Ajax.NET Professional实现之小小比较
    ASP.NET AJAX(Atlas)和Anthem.NET——管中窥豹般小小比较
    使用Anthem.NET 1.5中的FileUpload控件实现Ajax方式的文件上传
    Access中一句查询代码实现Excel数据导入导出
    Access中复制表
    tensorflow kmeans 聚类
    tensorflow knn mnist
  • 原文地址:https://www.cnblogs.com/guotianbao/p/7685544.html
Copyright © 2011-2022 走看看