组成部分

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. VMware虚拟机更换根用户( su: Authentication failure问题)

    su命令不能切换root,提示su: Authentication failure,只要你sudo passwd root过一次之后,下次再su的时候只要输入密码就可以成功登录了.

  2. sql查询以及常见问题理解解析

    推荐w3挺好的基础网站:https://www.w3cschool.cn/t_sql/t_sql_date_functions.html =,<,>,> =,<=,IN,BET ...

  3. CentOS添加并挂载新硬盘

    1.查看当前硬盘使用状况: [test@master Desktop]$ df -hFilesystem Size Used Avail Use% Mounted on/dev/sda2 13G 12 ...

  4. $python爬虫系列(2)—— requests和BeautifulSoup库的基本用法

    本文主要介绍python爬虫的两大利器:requests和BeautifulSoup库的基本用法. 1. 安装requests和BeautifulSoup库 可以通过3种方式安装: easy_inst ...

  5. 将CSV文件导入到hive数据库

    将csv文件导入hive后出现了所有的字段只显示在新建的表的第一个字段中,后面的字段全是null. 出现这种的原因是hive以行分隔数据,需要修改为按逗号'  ,  ‘ 进行分隔读取, 具体操作如下, ...

  6. Kafka内核理解:消息的收集/消费机制

    原文:https://www.cnblogs.com/daochong/p/6425762.html 一.Kafka数据收集机制 Kafka集群中由producer负责数据的产生,并发送到对应的Top ...

  7. Ruby 装pg的坑

    sudo apt-get install libpq-devsudo gem install pg -v '0.21.0'

  8. Java集合——TreeMap源码详解

    )TreeMap 是一个有序的key-value集合,它是通过红黑树实现的.因为红黑树是平衡的二叉搜索树,所以其put(包含update操作).get.remove的时间复杂度都为log(n). (2 ...

  9. Hbase操作table常见方法示例

    首先上我的输出类: /** * 功能:电池历史数据数据结构 * Created by liuhuichao on 2016/12/5. */ public class ResBatteryDataHi ...

  10. Kubernetes学习之路(九)之kubernetes命令式快速创建应用

    1.使用命令kubectl run创建应用 语法: kubectl run NAME --image=image [--env="key=value"] [--port=port] ...