权限管理——版本2

Posted Aray007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了权限管理——版本2相关的知识,希望对你有一定的参考价值。

权限管理——版本2 

1.完成目标

 菜单相关:
    [
        {\'menu_id\':1,\'menu_title\':\'菜单1\',\'title\':\'用户列表\',\'url\':\'/userinfo/\'},
        {\'menu_id\':1,\'menu_title\':\'菜单1\',\'title\':\'订单列表\',\'url\':\'/order/\'},
        {\'menu_id\':2,\'menu_title\':\'菜单2\',\'title\':\'xxx列表\',\'url\':\'/xxx/\'},
        {\'menu_id\':3,\'menu_title\':\'菜单2\',\'title\':\'aaa列表\',\'url\':\'/aaa/\'},
    ]

    菜单1
        用户管理

    菜单2
        订单管理

    分级,默认展开选中。

    构建数据结构:
        {
            1: {
                    \'menu_id\': 1,
                    \'menu_title\': \'菜单一\',
                    \'active\': None,
                    \'children\': [
                            {\'title\': \'订单列表\', \'url\': \'/order/\', \'active\': None}
                        ]
                    }
            2: {
                \'menu_id\': 2,
                \'menu_title\': \'菜单二\',
                \'active\': True,
                \'children\': [
                        {\'title\': \'用户列表\', \'url\': \'/userinfo/\', \'active\': True}
                    ]
                },

        }
    小结:  菜单相关的数据结构,还需要和当前请求的url匹配,匹配成功,actice为True。
            active有两个操作: 1.目标是否变红   2.目标是否展开或缩小。

 

5.从构建数据结构传过来的数据格式变了: 做了一个settings配置名,改以下就不需要每个地方都改。
6.循环数据,拿字典里面的key,value,字典套字典,要学会取值。
7.为了让视图知道codes,我们还需要取codes。
8.把生成菜单的标签放到simple_tag里load就可以了
9.扩展一个inclusion_tag自定义页面的功能,后面只需要跟一个页面。

 

结果实例图:

  

 

 

2.代码

1.app01/views.py

from django.shortcuts import render,redirect,HttpResponse
from rbac import models
from rbac.service.init_permission import init_permission
from django.conf import settings
import re


def login(reqeust):
    if reqeust.method == \'GET\':
        return  render(reqeust,\'login.html\')
    else:
        user = reqeust.POST.get(\'user\')
        pwd = reqeust.POST.get(\'pwd\')
        print(reqeust.POST)
        user = models.User.objects.filter(username=user,password=pwd).first()
        print(user)
        if not user:
            return render(reqeust,\'login.html\')
        init_permission(user,reqeust)
        print(111)
        return redirect(\'/index/\')


def index(request):
    print(222)
    return HttpResponse(\'欢迎登录   哈哈哈\')

class BasePagePermission(object):
    def __init__(self,code_list):
        self.code_list = code_list
        
    def has_add(self):
        if \'add\' in self.code_list:
            return True
    
    def has_edit(self):
        if \'edit\' in self.code_list:
            return True
        
    def has_del(self):
        if \'del\' in self.code_list:
            return True

def userinfo(request):
    print(request.permisstion_code_list)
    page_permission = BasePagePermission(request.permisstion_code_list)
    data_list = [
        {\'id\':1,\'name\':\'xxx1\'},
        {\'id\':2,\'name\':\'xxx2\'},
        {\'id\':3,\'name\':\'xxx3\'},
        {\'id\':4,\'name\':\'xxx4\'},
        {\'id\':5,\'name\':\'xxx5\'},
    ]

    menu_list = request.session[settings.PERMISSTION_MENU_KEY]

    return render(request,\'userinfo.html\',{\'data_list\':data_list,\'page_permission\':page_permission})




def userinfo_add(request):
    page_permission = BasePagePermission(request.permisstion_code_list)
    return HttpResponse(\'添加用户页面\')


class OrderPagePermission(BasePagePermission):
    def has_report(self):
        if \'report\' in self.code_list:
            return True


def order(request):
    order_permission = OrderPagePermission(request.permisstion_code_list)
    return render(request, \'order.html\')
views.py

 

2.settings:

STATIC_URL = \'/static/\'

PERMISSTION_URL_DICT = \'permissions_url_dict\'
PERMISSTION_MENU_KEY = \'asdasdasdada\'
VALID_URL = [
    \'/login/\',
    \'/admin.*/\'

]

 

3.urls.py

from django.conf.urls import url
from django.contrib import admin

from rbac import views
from app01 import views as app01_views

urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^test/\',views.test),
    url(r\'^login/\',app01_views.login),
    url(r\'^index/\',app01_views.index),
    url(r\'^userinfo/$\',app01_views.userinfo),
    url(r\'^userinfo/add$\',app01_views.userinfo_add),
    url(r\'^order/$\',app01_views.order)


]

 

4.rbac/middlewares/rbac.py

import re
from permission import settings

from django.shortcuts import redirect,HttpResponse


class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, \'process_request\'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, \'process_response\'):
            response = self.process_response(request, response)
        return response

class RbacMiddleware(MiddlewareMixin):
    def process_request(self,request):
        \'\'\'
           1.获取当前请求的url: 使用  request.path_info
           2.获取session中的保存的用户权限: 使用request.session.get().不能request.session[],因为可能没数据。
           3.设置白名单,获取到白名单的放行数据,和用户所拥有的权限url,匹配。 如果匹配,就不需要经过权限的检查。
           4.当用户访问了组的列表页面后,就应该知道他在这个组里还有什么权限。
                -1.分组: 1可以是用户组, 2是订单组
                -2.不当是用户列表页面需要知道他的所有权限,其它页面也应该知道。使用codes来获取。
                -3. 以上这样设置,不管什么页面都能知道所有的权限url,找到codes就可以。
                        list = {
                        1:{
                            \'codes\':[\'list\',\'add\',\'edit\',\'del\']
                            \'urls\':[
                            /userinfo/
                            /userinfo/add/
                            /userinfo/edit/(\\d+)/
                            /userinfo/del/(\\d+)/
                            ]
                        }
                    }
            5.从构建数据结构传过来的数据格式变了: 做了一个settings配置名,改以下就不需要每个地方都改。
            6.循环数据,拿字典里面的key,value,字典套字典,要学会取值。
            7.为了让视图知道codes,我们还需要取codes。
            8.把生成菜单的标签放到simple_tag里load就可以了
            9.扩展一个inclusion_tag自定义页面的后面只需要跟一个页面。
             \'\'\'
        current_url = request.path_info
        
        for url in settings.VALID_URL:
            if re.match(url,current_url):
                print(url,current_url)
                return None


        permission_dict = request.session.get(settings.PERMISSTION_URL_DICT)  # 拿到url格式的数据
        if not permission_dict:
            return redirect(\'/login/\')
        flag = False
        for group_id,code_url in permission_dict.items():  # 用in不行,含正则的url使用in会匹配不了,所要要用正则:re.match
            for db_url  in code_url[\'urls\']:
                regax =  \'^{0}$\'.format(db_url) #加上起止符,绝对匹配。
                if re.match(regax, current_url):  # 如果匹配成功,就已等
                    request.permisstion_code_list = code_url[\'codes\']   #取到codes列表,存到request里
                    flag = True
                    break
            if flag:
                break
        if not flag:
            return HttpResponse(\'无权访问\')
rbac.py

 

5.rbac/service/init_permission.py

from django.conf import  settings

def init_permission(user,request):
    \'\'\'
    初始化权限信息,把权限url放到session。
    :param user:
    :param request:
    :return:

    list = {
    1:{
        \'codes\':[\'list\',\'add\',\'edit\',\'del\']
        \'urls\':[
        /userinfo/
        /userinfo/add/
        /userinfo/edit/(\\d+)/
        /userinfo/del/(\\d+)/
        ]
    }
}

    菜单相关:
    [
        {\'menu_id\':1,\'menu_title\':\'菜单1\',\'title\':\'用户列表\',\'url\':\'/userinfo/\'},
        {\'menu_id\':1,\'menu_title\':\'菜单1\',\'title\':\'订单列表\',\'url\':\'/order/\'},
        {\'menu_id\':2,\'menu_title\':\'菜单2\',\'title\':\'xxx列表\',\'url\':\'/xxx/\'},
        {\'menu_id\':3,\'menu_title\':\'菜单2\',\'title\':\'aaa列表\',\'url\':\'/aaa/\'},
    ]

    菜单1
        用户管理

    菜单2
        订单管理

    分级,默认展开选中。

    构建数据结构:
        {
            1: {
                    \'menu_id\': 1,
                    \'menu_title\': \'菜单一\',
                    \'active\': None,
                    \'children\': [
                            {\'title\': \'订单列表\', \'url\': \'/order/\', \'active\': None}
                        ]
                    }
            2: {
                \'menu_id\': 2,
                \'menu_title\': \'菜单二\',
                \'active\': True,
                \'children\': [
                        {\'title\': \'用户列表\', \'url\': \'/userinfo/\', \'active\': True}
                    ]
                },

        }
    小结:  菜单相关的数据结构,还需要和当前请求的url匹配,匹配成功,actice为True。
            active有两个操作: 1.目标是否变红   2.目标是否展开或缩小。
    \'\'\'
    permission_list2 = user.roles.values(\'permissions__title\', #权限名称
                                         \'permissions__url\',   #权限url
                                         \'permissions__is_menu\', #权限是否是菜单
                                         \'permissions__codes\',  #权限的codes
                                         \'permissions__group_id\',   #组id
                                         \'permissions__group__menu_id\', #菜单id
                                         \'permissions__group__menu__title\' #菜单名称
                                         ).distinct()
    menu_list = []
    #去掉不是菜单的url
    for item in permission_list2:
        if not item[\'permissions__is_menu\']:
            continue
        tpl = {
            \'menu_id\':item[\'permissions__group__menu_id\'],
            \'menu_title\':item[\'permissions__group__menu__title\'],
            \'title\':item[\'permissions__title\'],
            \'url\':item[\'permissions__url\'],
            \'active\':False
        }
        menu_list.append(tpl)
    request.session[settings.PERMISSTION_MENU_KEY] = menu_list


    #权限相关
    result = {}
    for item in  permission_list2:
        group_id = item[\'permissions__group_id\']
        code = item[\'permissions__codes\']
        url = item[\'permissions__url\']
        if group_id in result:
            result[group_id][\'codes\'].append(code)
            result[group_id][\'urls\'].append(url)
        else:
            result[group_id] = {
                \'codes\':[code,],
                \'urls\':[url,],
            }
    request.session[settings.PERMISSTION_URL_DICT] = result

    #拿到用户请求url,和session做对比,如果在,可访问,不在,一边去。
View Code

 

6.rbac/static/rabc/rbac.css

.item-permission{
    padding: 3px 10px;
}
.item-permission a{
    display: block;
}
.item-permission a.active{
    color: red;
}
.hide{
    display: none;
}
View Code

 

7..rbac/static/rabc/rbac.js

/**
 * Created by Administrator on 2017/11/8.
 */
 $(function () {
    $(\'.item-title\').click(function () {
        if($(this).next().hasClass(\'hide\')){
            $(this).next().removeClass(\'hide\')
        }else{
            $(this).next().addClass(\'hide\')
        }
    })


});

 

8.rbac/templatetags/rbac.py

import re
from django.template import Library
from django.conf import settings
register = Library()

@register.inclusion_tag(\'xxxxx.html\')
def menu_html(request):
    \'\'\'
    去session中获取菜单相关信息,匹配当前url,生成菜单。
    :param request: 
    :return: 
    \'\'\'

    menu_list = request.session[settings.PERMISSTION_MENU_KEY]
    current_url = request.path_info
    result = {}
    for item in menu_list:
        url = item[\'url\']
        print(url)
        regex = \'^{0}$\'.format(url)
        active = False
        if re.match(regex,current_url):
            active = True
        menu_id = item[\'menu_id\']
        if menu_id in result:
            result[menu_id][\'children\'].append({\'title\':item[\'title\'],\'url\':item[\'url\'],\'active\':active})
            if active:
                result[menu_id][\'active\'] = True
        else:
            result[menu_id] = {
                \'menu_id\':menu_id,
                \'menu_title\':item[\'menu_title\'],
                \'active\': active,
                \'children\': [
                    {\'title\': item[\'title\'], \'url\': item[\'url\'], \'active\': active},
                ]
            }
    return {\'menu_dict\':result}
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
View Code

 

9.xxxxx.html

{% for k,item in menu_dict.items %}
    <div class="item">
        <div class="item-title">{{ item.menu_title }}</div>
        {% if item.active %}
            <div class="item-permission">
        {% else %}
            <div class="item-permission hide">
        {% endif %}
            {% for v in item.children %}

                {% if v.active %}
                    <a href="{{ v.url }}" class="active">{{ v.title }}</a>
                {% else %}
                    <a href="{{ v.url }}">{{ v.title }}</a>
                {% endif %}

            {% endfor %}
        </div>
    </div>
{% endfor %}

 

以上是关于权限管理——版本2的主要内容,如果未能解决你的问题,请参考以下文章

PHP Wordpress - 删除更新唠叨和版本给所有人,但管理员(2个片段)

JS+JavaBean判断管理员增删改的操作权限

gitlab 权限说明

Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段

Oracle-常用数据库对象笔记(片段)

Shiro权限管理2.Shiro的HelloWorld程序