Django_用户权限管理rbac
组成部分
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的更多相关文章
- devops-jenkins基于角色的权限管理RBAC
一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理 1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...
- 练习:python 操作Mysql 实现登录验证 用户权限管理
python 操作Mysql 实现登录验证 用户权限管理
- django 基于proxy实现用户权限管理
项目中经常会遇到用户权限管理的问题,django adminsite已经提供非常实用的用户权限管理机制.不过有些时候,我们希望根据相关用户属性来过滤adminsite中显示的内容.下文将结束如何实现: ...
- RDIFramework.NET ━ 9.8 用户权限管理 ━ Web部分
RDIFramework.NET ━ .NET快速信息化系统开发框架 9.8 用户权限管理 -Web部分 在实际应用中我们会发现,权限控制会经常变动,如:需要调整角色的分配,需要收回与授予某些角色.用 ...
- Python 学习 第十篇 CMDB用户权限管理
Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...
- Oracle 用户权限管理方法
Oracle 用户权限管理方法 sys;//系统管理员,拥有最高权限 system;//本地管理员,次高权限 scott;//普通用户,密码默认为tiger,默认未解锁 sys;//系统管理员,拥有最 ...
- Oracle SQL 基本操作之 用户权限管理方法
Oracle SQL 基本操作之 用户权限管理方法 最近把有关用户操作和权限管理的东西整理了一下,虽然不少博客都有过类似的整理,但是自己发现他们的内容或多或少都有些错误.于是,本人亲自对每条语句进行 ...
- 如何对MongoDB 3.2.7进行用户权限管理配置
转自:https://www.jianshu.com/p/a4e94bb8a052 上次写了一篇在CentOS7上源码安装MongoDB 3.2.7,完成了MongoDB 3.2.7的安装,但需要应用 ...
- [原]Jenkins(十三)---jenkins用户权限管理
* 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horizonli/p/5337874.html 两种策略的比较
随机推荐
- IFsvnadmin svn界面管理工具
安装部署if.svnadmin 工具 前提是安装好svn服务器及apache+php服务器. yum -y install subversion mod_dav_svn 安装完建立一个目录用来作为sv ...
- jenkins -Djava.awt.headless=true Linux下java.awt.HeadlessException的解决办法
修改 linux apache-tomcat-7.0.56/bin \catalina.sh文件 在所有类似以下代码大约有七八处具体自己去看: "$_RUNJAVA" $J ...
- select * from * with ur
DB2中,共有四种隔离级:RS,RR,CS,UR,DB2提供了这4种不同的保护级别来隔离数据.隔离级是影响加锁策略的重要环节,它直接影响加锁的范围及锁的持续时间.两个应用程序即使执行的相同的操作,也可 ...
- 使用putty进行ssh tunnel远程内网机器
通常我们通过登录具有外网ip的远程机器来连接内网的机器:本文介绍,通过putty进行ssh tunnel,进而达到使用本机直接连接远程内网机器: 1,在putty中创建一个session,输入具有外网 ...
- 面向对象之static关键字
static概念 static它是静态修饰符,一般用来修饰类中的成员. static特点 1.多个对象共享一个static成员变量.一个对象将static成员变量值修改了,其他对象中的static成员 ...
- starshot常见问题(New)
Element组件网址: http://element-cn.eleme.io/#/zh-CN/component/message Layer组件网址: https://www.layui.com/d ...
- 使用zabbix发送邮件的简易设置流程(存档用)
1.安装邮件软件 (一般默认安装sendmail,这样apache也不用重新设置.) $sudo yum install sendmail 2.在zabbix上设置发送邮件用的本地邮箱 选择管理-&g ...
- jQuery学习-页面就绪函数
1.开发工具HBuilder <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...
- CF 1114 E. Arithmetic Progression
E. Arithmetic Progression 链接 题意: 交互题. 有一个等差序列,现已打乱顺序,最多询问60次来确定首项和公差.每次可以询问是否有严格大于x的数,和查看一个位置的数. 分析: ...
- directive指令二 require:'^ngModel'
本章主要是讲指令与ngModel的交互. 在angular有一个内置指令叫ngModel,它是angular用来处理表单的最重要的指令.在源码中,页面上的model值的格式化.解析.验证都是由ngMo ...