权限管理——版本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\')
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(\'无权访问\')
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做对比,如果在,可访问,不在,一边去。
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; }
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}
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个片段)
Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段