组成部分

1、初始化权限:login视图initial_permission,把权限信息放入session。initial_permission函数生成权限列表、菜单列表

2、中间件验证权限:在第一次登陆后,使用中间件的process_request检验用户的权限情况,同时,也有白名单RBAC_NO_AUTH_URL放在settings.py

3、simple_tag生成菜单

重点代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django.conf import settings
from .. import models def initial_permission(request, user):
"""
初始化权限,获取当前用户权限并添加到session中 :param request: 请求对象
:param user: 当前用户对象
:return:
"""
# 1.获取当前用户所有角色 user.roles.all()
# roles = user.roles.all() # 2.获取角色对应的所有权限
permission_list = user.roles.values('permissions__id', 'permissions__caption', 'permissions__url',
'permissions__menu_id').distinct() permission_url_list = []
permission_menu_list = []
for item in permission_list:
permission_url_list.append(item['permissions__url'])
if item['permissions__menu_id']:
permission_menu_list.append(item) # 3. 权限写入session
request.session[settings.RBAC_PERMISSION_URL_SESSION_KEY] = permission_url_list # 4. 菜单写入session
menu_list = list(models.Menu.objects.values('id', 'caption', 'parent_id'))
request.session[settings.RBAC_MENU_PERMISSION_SESSION_KEY] = {
settings.RBAC_MENU_KEY: menu_list,
settings.RBAC_MENU_PERMISSION_KEY: permission_menu_list
} pro_admin(项目名)/arya/service/rbac.py

pro_admin(项目名)/arya/service/rbac.py

def login(self, request):
"""
用户登录
:param request:
:return:
"""
from arya import models
from arya.service import rbac # 测试
# obj = models.User.objects.get(id=1)
# rbac.initial_permission(request, obj) # 初始化权限信息
#
# return HttpResponse('Login') if request.method == 'GET':
return render(request, 'login.html')
else:
from arya import models
from arya.service import rbac user = request.POST.get('username')
pwd = request.POST.get('password')
obj = models.User.objects.filter(username=user, password=pwd).first()
if obj:
rbac.initial_permission(request, obj)
return redirect('/arya/')
else:
return render(request, 'login.html')

视图函数login

#!/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
from django.utils.safestring import mark_safe 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_url_list = request.session.get(settings.RBAC_PERMISSION_URL_SESSION_KEY)
if not permission_url_list:
return HttpResponse(settings.RBAC_PERMISSION_MSG) """当前URL和session中的权限进行匹配"""
flag = False
for url in permission_url_list:
pattern = settings.RBAC_MATCH_PARTTERN.format(url)
if re.match(pattern, request.path_info):
flag = True
break if not flag:
if settings.DEBUG:
return HttpResponse("无权访问,你的权限有:<br/>" + mark_safe("<br/>".join(permission_url_list)))
else:
return HttpResponse(settings.RBAC_PERMISSION_MSG)

pro_admin/arya/middleware/rbac.py中间件处理权限

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import os
from django import template
from django.utils.safestring import mark_safe
from django.conf import settings register = template.Library() def process_menu_tree_data(request):
"""
根据Session中获取的菜单以及权限信息,结构化数据,生成特殊数据结构,如:
[
{id:1,caption:'菜单标题',parent_id:None,status:False,opened:False,child:[...]},
]
PS: 最后一层的权限会有url,即:菜单跳转的地址 :param request:
:return:
"""
menu_permission_dict = request.session.get(settings.RBAC_MENU_PERMISSION_SESSION_KEY)
if not menu_permission_dict:
raise Exception('Session中未保存当前用户菜单以及权限信息,请登录后初始化权限信息!') """ session中获取菜单和权限信息 """
all_menu_list = menu_permission_dict[settings.RBAC_MENU_KEY]
menu_permission_list = menu_permission_dict[settings.RBAC_MENU_PERMISSION_KEY] all_menu_dict = {}
for row in all_menu_list:
row['opened'] = False
row['status'] = False
row['child'] = []
all_menu_dict[row['id']] = row """ 将权限信息挂靠在菜单上,并设置是否默认打开,以及默认显示 """
for per in menu_permission_list:
item = {'id': per['permissions__id'], 'caption': per['permissions__caption'], 'url': per['permissions__url'],
'parent_id': per['permissions__menu_id'],
'opened': False,
'status': True}
menu_id = item['parent_id']
all_menu_dict[menu_id]['child'].append(item) # 将当前URL和权限正则进行匹配,用于指示是否默认打开菜单
pattern = settings.RBAC_MATCH_PARTTERN.format(item['url'])
if re.match(pattern, request.path_info):
item['opened'] = True if item['opened']:
pid = menu_id
while not all_menu_dict[pid]['opened']:
all_menu_dict[pid]['opened'] = True
pid = all_menu_dict[pid]['parent_id']
if not pid:
break if item['status']:
pid = menu_id
while not all_menu_dict[pid]['status']:
all_menu_dict[pid]['status'] = True
pid = all_menu_dict[pid]['parent_id']
if not pid:
break result = []
for row in all_menu_list:
pid = row['parent_id']
if pid:
all_menu_dict[pid]['child'].append(row)
else:
result.append(row) return result def build_menu_tree_html(menu_list):
tpl1 = """
<div class='rbac-menu-item'>
<div class='rbac-menu-header'>{0}</div>
<div class='rbac-menu-body {2}'>{1}</div>
</div>
"""
tpl2 = """
<a href='{0}' class='{1}'>{2}</a>
"""
menu_str = ""
for menu in menu_list:
if not menu['status']:
continue if menu.get('url'):
menu_str += tpl2.format(menu['url'], 'rbac-active' if menu['opened'] else "" , menu['caption'])
else:
if menu.get('child'):
child = build_menu_tree_html(menu.get('child'))
else:
child = ""
menu_str += tpl1.format(menu['caption'], child, "" if menu['opened'] else 'rbac-hide')
return menu_str @register.simple_tag
def rbac_menu(request):
"""
根据Session中当前用户的菜单信息以及当前URL生成菜单
:param request: 请求对象
:return:
"""
menu_tree_list = process_menu_tree_data(request)
return mark_safe(build_menu_tree_html(menu_tree_list)) @register.simple_tag
def rbac_css():
file_path = os.path.join('arya', 'theme', settings.RBAC_THEME, 'rbac.css')
if os.path.exists(file_path):
return mark_safe(open(file_path, 'r', encoding='utf-8').read())
else:
raise Exception('rbac主题CSS文件不存在') @register.simple_tag
def rbac_js():
file_path = os.path.join('arya', 'theme', settings.RBAC_THEME, 'rbac.js')
if os.path.exists(file_path):
return mark_safe(open(file_path, 'r', encoding='utf-8').read())
else:
raise Exception('rbac主题JavaScript文件不存在')

pro_admin/arya/templatetags/arya.py使用simple_tag生成菜单栏

# ############################## RBAC权限相关配置开始 ##############################
# session中保存权限信息的Key
RBAC_PERMISSION_URL_SESSION_KEY = "rbac_permission_url_session_key" # 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" # 匹配URL时指定规则
RBAC_MATCH_PARTTERN = "^{0}$" # 无需权限控制的URL
RBAC_NO_AUTH_URL = [
'/arya/login',
] # 无权访问时,页面提示信息
RBAC_PERMISSION_MSG = "无权限访问" # 菜单主题
RBAC_THEME = "default"
# ############################## RBAC权限相关配置结束 ##############################

settings.py

具体代码:

fork wupeiqi的,结合arya:https://github.com/fat39/pro_admin

fork wupeiqi的,有curd的actions models:https://github.com/fat39/Rbacdemo

Django_用户权限管理rbac的更多相关文章

  1. devops-jenkins基于角色的权限管理RBAC

    一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理  1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...

  2. 练习:python 操作Mysql 实现登录验证 用户权限管理

    python 操作Mysql 实现登录验证 用户权限管理

  3. django 基于proxy实现用户权限管理

    项目中经常会遇到用户权限管理的问题,django adminsite已经提供非常实用的用户权限管理机制.不过有些时候,我们希望根据相关用户属性来过滤adminsite中显示的内容.下文将结束如何实现: ...

  4. RDIFramework.NET ━ 9.8 用户权限管理 ━ Web部分

    RDIFramework.NET ━ .NET快速信息化系统开发框架 9.8 用户权限管理 -Web部分 在实际应用中我们会发现,权限控制会经常变动,如:需要调整角色的分配,需要收回与授予某些角色.用 ...

  5. Python 学习 第十篇 CMDB用户权限管理

    Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...

  6. Oracle 用户权限管理方法

    Oracle 用户权限管理方法 sys;//系统管理员,拥有最高权限 system;//本地管理员,次高权限 scott;//普通用户,密码默认为tiger,默认未解锁 sys;//系统管理员,拥有最 ...

  7. Oracle SQL 基本操作之 用户权限管理方法

     Oracle SQL 基本操作之 用户权限管理方法 最近把有关用户操作和权限管理的东西整理了一下,虽然不少博客都有过类似的整理,但是自己发现他们的内容或多或少都有些错误.于是,本人亲自对每条语句进行 ...

  8. 如何对MongoDB 3.2.7进行用户权限管理配置

    转自:https://www.jianshu.com/p/a4e94bb8a052 上次写了一篇在CentOS7上源码安装MongoDB 3.2.7,完成了MongoDB 3.2.7的安装,但需要应用 ...

  9. [原]Jenkins(十三)---jenkins用户权限管理

    * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horizonli/p/5337874.html 两种策略的比较

随机推荐

  1. Srv数据格式

    1.简介 类似msg文件, srv文件是用来描述服务( service数据类型的, service通信的数据格式定义在*.srv中. 它声明了一个服务, 包括请求(request)和响应( reply ...

  2. kaggle _Titanic: Machine Learning from Disaster

    A Data Science Framework: To Achieve 99% Accuracy https://www.kaggle.com/ldfreeman3/a-data-science-f ...

  3. 一个考验c语言和数据结构功底的小项目

    想测一下自己c语言学习水平的朋友可以做一下这个项目试试,能做出来说明c语言已经入门了   #include<stdio.h> #include<stdlib.h> #inclu ...

  4. XCode iOS之应用程序标题本地化

    1.XCode项目中创建一个.strings 扩展名的文件:打开File > New > File,选择Resource中Strings Fils,如图:点击下一步,为文件命名为(强烈建议 ...

  5. mysql数据库使用insert语句插入中文数据报错

    在mysql的命令行模式中,通过insert语句插入中文数据的时候报错,类似于下面这样: Incorrect string value: '\xE7\x8F' for column 'name' at ...

  6. jQuery hide() 参数callback回调函数执行问题

    $("#b").click(function() { $("div").hide(1000,bbb); //-------------1 bbb是一个函数,但这 ...

  7. windows下beautifulsoup使用lxml解析使用报错

    s4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need ...

  8. Linux下onvif客户端获取ipc摄像头 获取能力:GetCapabilities

    GetCapabilities:获取能力,主要目的获取设备能力信息(获取媒体服务地址) 鉴权:但是在调用获取设备能力之前是需要鉴权的.ONVIF协议规定,部分接口需要鉴权,部分接口不需要鉴权,在调用需 ...

  9. telerik WinForm主题切换

    通过按钮或Form_Load中切换: ThemeResolutionService.ApplicationThemeName = "Windows 7"; //具体的主题名,不同的 ...

  10. JavaWeb基础—JSP

    一.什么是JSP JSP 全称是 Java Server Pages,是一种开发动态web资源的技术 在原HTML上添加JAVA脚本(灵魂工程师,为页面添加灵魂),可以说 jsp = html + j ...