【django之权限组件】
一、需求分析
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间都是多对多的关系。
一个可访问的含正则表达式的url就是一个权限,利用角色控制访问url。

二、功能实现
1、目录树

2、数据库设计
用户组,角色,权限
from django.db import models # Create your models here. class User(models.Model):
name=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
roles=models.ManyToManyField("Role") def __str__(self):
return self.name class Role(models.Model):
title=models.CharField(max_length=32)
permissions=models.ManyToManyField("Permission")
def __str__(self):
return self.title class Permission(models.Model):
url=models.CharField(max_length=32)
title=models.CharField(max_length=32,default="")
p_group=models.ForeignKey("PermissionGroup",default=1)
code=models.CharField(max_length=32,default="list",)
def __str__(self):
return self.title class PermissionGroup(models.Model):
name=models.CharField(max_length=32)
def __str__(self):
return self.name
models.py
3、登录验证
将登录用户的所有权限信息注入到session中
rbac/service/initail.py
def permission_session(user,request):
# 将当前user的所有权限注入session中 # 方式1:
#permissions = user.roles.all().values("permissions__url").distinct()
# permission_list = []
# for i in permissions:
# permission_list.append(i.get("permissions__url"))
#
# request.session["permission_list"] = permission_list # 方式2:
permissions = user.roles.all().values("permissions__url","permissions__p_group_id","permissions__code").distinct() # print(permissions) permission_dict={}
for permission in permissions:
p_group_id=permission.get("permissions__p_group_id") if p_group_id in permission_dict:
permission_dict[p_group_id]["urls"].append(permission.get("permissions__url"))
permission_dict[p_group_id]["codes"].append(permission.get("permissions__code"))
else:
permission_dict[p_group_id]={
"urls":[permission.get("permissions__url")],
"codes":[permission.get("permissions__code")],} print(permission_dict) request.session["permission_dict"]=permission_dict
4、基于中间件做权限校验
功能: 1.白名单验证;
2.验证是否已经写入session,即:是否已经登录;
3.当前访问的url与当前用户的权限url进行匹配验证,并在request中写入code信息
settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "rbac.service.rbac.PermissionValid",
]
rabc.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
class PermissionValid(MiddlewareMixin):
    def process_request(self,request):
        valid_url=["/login/","/reg/","/admin/.*"]      #白名单
        import re
        for url in valid_url:
            url="^%s$"%url
            ret=re.match(url,request.path_info)
            if ret:
                return None
    #.验证是否已经写入session,即:是否已经登录
        if not request.session.get("user_id"):
            return redirect("/login/")
        current_path = request.path_info
        # 方式1:
        # permission_list = request.session.get("permission_list")
        #
        # import re
        #
        # flag = False
        # for permission in permission_list:
        #     permission="^%s$"%permission
        #     ret = re.match(permission, current_path)
        #     if ret:
        #         flag = True
        #         break
        # if not flag:
        #     return HttpResponse("无权访问")
        # 方式2:
    #与当前访问的url与权限url进行匹配验证,并在request中写入code信息,
        permission_dict = request.session.get("permission_dict")
        import re
        flag = False
        for item in permission_dict.values():
            urls=item["urls"]
            for permission in urls:
                 permission="^%s$"%permission
                 ret = re.match(permission, current_path)
                 if ret:
                    print("codes",item.get("codes"))
                    request.codes=item.get("codes")
                    return None
        return HttpResponse("无权访问")
三、代码
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from rbac.models import * class PermissionCode(object):
def __init__(self,codes):
self.codes=codes
def list(self):
return "list" in self.codes
def add(self):
return "add" in self.codes
def edit(self):
return "edit" in self.codes
def delete(self):
return "del" in self.codes def users(request): user_list=User.objects.all() per=PermissionCode(request.codes) return render(request,"users.html",locals()) def add_users(request): return HttpResponse("添加用户") def change_users(request,id): return HttpResponse("编辑用户")
def delete_users(request,id): return HttpResponse("删除用户") def login(request):
if request.method=="POST":
user=request.POST.get("user")
pwd=request.POST.get("pwd") user=User.objects.filter(name=user,pwd=pwd).first() if user: request.session["user_id"]=user.pk from rbac.service.initail import permission_session
permission_session(user,request) return HttpResponse("登录成功") return render(request,"login.html")
app01/views.py
def permission_session(user,request):
# 将当前user的所有权限注入session中 # 方式1:
#permissions = user.roles.all().values("permissions__url").distinct()
# permission_list = []
# for i in permissions:
# permission_list.append(i.get("permissions__url"))
#
# request.session["permission_list"] = permission_list # 方式2:
permissions = user.roles.all().values("permissions__url","permissions__p_group_id","permissions__code").distinct() # print(permissions) permission_dict={}
for permission in permissions:
p_group_id=permission.get("permissions__p_group_id") if p_group_id in permission_dict:
permission_dict[p_group_id]["urls"].append(permission.get("permissions__url"))
permission_dict[p_group_id]["codes"].append(permission.get("permissions__code"))
else:
permission_dict[p_group_id]={
"urls":[permission.get("permissions__url")],
"codes":[permission.get("permissions__code")],} print(permission_dict) request.session["permission_dict"]=permission_dict
rabc/service/initail.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
class PermissionValid(MiddlewareMixin):
    def process_request(self,request):
        valid_url=["/login/","/reg/","/admin/.*"]      #白名单
        import re
        for url in valid_url:
            url="^%s$"%url
            ret=re.match(url,request.path_info)
            if ret:
                return None
    #.验证是否已经写入session,即:是否已经登录
        if not request.session.get("user_id"):
            return redirect("/login/")
        current_path = request.path_info
        # 方式1:
        # permission_list = request.session.get("permission_list")
        #
        # import re
        #
        # flag = False
        # for permission in permission_list:
        #     permission="^%s$"%permission
        #     ret = re.match(permission, current_path)
        #     if ret:
        #         flag = True
        #         break
        # if not flag:
        #     return HttpResponse("无权访问")
        # 方式2:
    #与当前访问的url与权限url进行匹配验证,并在request中写入code信息,
        permission_dict = request.session.get("permission_dict")
        import re
        flag = False
        for item in permission_dict.values():
            urls=item["urls"]
            for permission in urls:
                 permission="^%s$"%permission
                 ret = re.match(permission, current_path)
                 if ret:
                    print("codes",item.get("codes"))
                    request.codes=item.get("codes")
                    return None
        return HttpResponse("无权访问")
rabc/service/rabc.py
from django.contrib import admin # Register your models here. from .models import * admin.site.register(User)
admin.site.register(Role) class PermissionConfig(admin.ModelAdmin):
list_display = ["title","url","p_group","code"]
admin.site.register(Permission,PermissionConfig)
admin.site.register(PermissionGroup)
rabc/admin.py
from django.db import models # Create your models here. class User(models.Model):
name=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
roles=models.ManyToManyField("Role") def __str__(self):
return self.name class Role(models.Model):
title=models.CharField(max_length=32)
permissions=models.ManyToManyField("Permission")
def __str__(self):
return self.title class Permission(models.Model):
url=models.CharField(max_length=32)
title=models.CharField(max_length=32,default="")
p_group=models.ForeignKey("PermissionGroup",default=1)
code=models.CharField(max_length=32,default="list",)
def __str__(self):
return self.title class PermissionGroup(models.Model):
name=models.CharField(max_length=32)
def __str__(self):
return self.name
rabc/models.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
"rbac.apps.RbacConfig",
] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"rbac.service.rbac.PermissionValid", ]
settings.py
from django.conf.urls import url
from django.contrib import admin from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/$', views.login),
url(r'^users/$', views.users),
url(r'^users/add/$', views.add_users),
url(r'^users/(\d+)/change/$', views.change_users),
url(r'^users/(\d+)/delete/$', views.delete_users),
]
urls.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="" method="post">
{% csrf_token %}
用户名:<input type="text" name="user">
密码:<input type="text" name="pwd">
<input type="submit">
</form> </body>
</html>
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container">
<h3>查看用户</h3> <div class="col-md-6">
{% if per.add %}
<a href="/users/add/" class="btn btn-primary">添加用户</a>
{% endif %} <table class="table table-borderd table-striped col-md-offset-4">
{% for user in user_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.name }}</td> {% if per.edit %}
<td><a href="/users/{{ user.pk }}/change" class="btn btn-success">编辑</a></td>
{% endif %} {% if per.delete %}
<td><a href="/users/{{ user.pk }}/delete/" class="btn btn-success">删除</a></td>
{% endif %} </tr>
{% endfor %}
</table>
</div>
</div> </body>
</html>
templates/users.html
【django之权限组件】的更多相关文章
- Django框架----权限组件(具体代码实现)
		
1.settings """ Django settings for day80 project. Generated by 'django-admin startpro ...
 - Django的rest_framework的权限组件和频率组件源码分析
		
前言: Django的rest_framework一共有三大组件,分别为认证组件:perform_authentication,权限组件:check_permissions,频率组件:check_th ...
 - Django - 权限分配、权限组件与CRM整合
		
一.权限分配 需求:为用户分配角色,为角色分配权限,如下图效果: 1.视图代码: from django.shortcuts import render from django.http import ...
 - Django REST framework —— 权限组件源码分析
		
在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...
 - Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)
		
一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...
 - Django万能权限框架组件
		
业务场景分析 假设我们在开发一个培训机构的 客户关系管理系统,系统分客户管理.学员管理.教学管理3个大模块,每个模块大体功能如下 客户管理 销售人员可以录入客户信息,对客户进行跟踪,为客户办理报名手续 ...
 - $Django Rest Framework-认证组件,权限组件 知识点回顾choices,on_delete
		
一 小知识点回顾 #orm class UserInfo (models.Model): id = models.AutoField (primary_key=True) name = models. ...
 - Django高级篇三。restful的解析器,认证组件,权限组件
		
一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...
 - 巨蟒django之权限10,内容梳理&&权限组件应用
		
1.CRM项目内容梳理: 2.权限分配 3.权限组件的应用
 
随机推荐
- windows共享虚拟机ubuntu目录
			
1)安装 sudo apt-get install samba 2)配置文件vi /etc/samba/smb.conf 添加如下 3)启动服务 sudo service smbd start 4)w ...
 - 编译器重复定义错误:error C2371: 'SIZE' : redefinition; different basic types
			
我们常常会定义自己工程用的数据类型,可能会与Windows的基本数据类型冲突. vs会报重复定义错误:error C2371: 'SIZE' : redefinition; different bas ...
 - 深究ASP.NET Session
			
Session 本质 & 访问方法 Session 本质 是 HttpSessionState 类 link Session 访问方法 HttpContext.Session Page.Ses ...
 - ASP.NET WebForm 通过 PagedDataSource 实现 Repeater 的分页
			
1.效果图&代码说明 1.效果图 2.代码说明 1.翻页按钮 前台两个LinkButton(上一页.下一页),设置不同的CommandName.CommandArg ...
 - ssm整合快速入门程序(一)
			
整合基础说明 spring 是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的Jav ...
 - 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)
			
[BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...
 - [Luogu2073]送花
			
题面 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地 ...
 - angularjs中的下拉框默认选中
			
1. ng-init 属性: <!DOCTYPE html> <html> <head> <meta charset="utf-8"& ...
 - 《阿里巴巴Android编码规范》阅读纪要(一)
			
版权声明:本文出自汪磊的博客,转载请务必注明出处. 2月28日阿里巴巴首次公开内部安卓编码规范,试想那么多业务线,开发人员,没有一套规范管理起来是多么麻烦,以下是个人阅读Android基本组件部分过程 ...
 - Spring Boot初探之数据库访问
			
一.背景 Spring boot是集服务发布.数据库管理.日志管理等于一身的服务开发框架:是微服务开发的全能小帮手.这章讲述一下如何使用spring boot访问MySQL数据库. 二.搭建基础环境 ...