组成部分

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. oracle 基本知识点

    //创建临时表空间create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserver ...

  2. 差异是关键,TI首款隔离式CAN收发器评析

    差异是关键,TI首款隔离式CAN收发器评析           “无论是在日常生活还是媒体报道中, CAN接口对大家来说已经司空见惯了,然而将CAN接口和隔离功能整合在同一产品里,这还是业界头一遭,” ...

  3. zdump 命令查看时区和夏令时

    zdump -v 时区名称1. 查看中国PRC时区的2007年的时区规则# zdump -v PRC | grep 2009PRC Mon Sep 17 06:03:55 2007 UTC = Mon ...

  4. #leetcode刷题之路33-搜索旋转排序数组

    假设按照升序排序的数组在预先未知的某个点上进行了旋转.( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ).搜索一个给定的目标值,如果数组中存在这个目标值,则返 ...

  5. 0CO_PC_ACT_10 不能提取NV类别的数据

    今天用 BW 标准数据源 0CO_PC_ACT_10 提取数据时,发现物料有一项数据[没有被分摊]无法取到. 根据SAP的解释,此项不在后台存数,通过前台动态生成. For the virtual c ...

  6. MacOS在Finder中建立快速新建txt的workflow

    Mac是不支持右键直接新建txt的,因此有时候需要用到文本文稿的时候会比较麻烦.   因此这里提供一种个人认为比较方便的方法,让Mac也能很简洁的新建txt文件.   工具介绍: Automator ...

  7. 在vivado中自定义编辑器

    在 Tools - Options - Text Editor 中选择 Custom Editor 这里我用的gvim,在Editor文本框中输入: C:/Vim/vim80/gvim.exe --r ...

  8. 2 python介绍

    1.Python介绍:龟叔 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写Python语言的编译器.Python这个名字,来自Gui ...

  9. 17-[模块]-time&datetime

    1.表示时间time方式 在Python中,用三种方式来表示时间,分别是时间戳.格式化时间字符串和结构化时间 1.时间戳(timestamp):也就是1970年1月1日之后的秒, 例如15063882 ...

  10. 9 ORM-高阶补充(未完成)

    https://www.cnblogs.com/alice-bj/p/9195846.html#_labelTop https://www.cnblogs.com/yuanchenqi/article ...