Django——权限组件(中间件判断用户权限–URL初级)
大家在学习,写项目的时候或多或少的了解过一些,关于RBAC的知识点。
简单介绍 RBAC
RBAC是什么?
RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
RBAC介绍。
RBAC 认为授权实际上是Who 、What 、How 三元组之间的关系,也就是Who 对What 进行How 的操作,也就是“主体”对“客体”的操作。
- Who:是权限的拥有者或主体(如:User,Role)。
- What:是操作或对象(operation,object)。
- How:具体的权限(Privilege,正向授权与负向授权)。
然后 RBAC 又分为RBAC0、RBAC1、RBAC2、RBAC3。后期我会介绍。
简单的了解了概念后,我们来看下他基本的使用方法。
问题:
在了解了 RBAC后知道了,角色都有对应的权限,我们大胆的设想下。在 一个项目中,每一个 点击事件资源的请求,都可能是会对用户的权限来进行判断。结合了 Restful的思想,资源的请求,还分为:Get,Post,Put,Delete方法。这些方法的权限也都需要来进行判断。
下面开始演示
Pyhton中RBAC的设计思路
-
数据库层面(models)
用户、角色、权限、权限组、菜单(菜单只是为了在页面展示以及菜单作用)
-
中间件层(middlewares)
中间件层是在用户请求服务器最前面的一层过滤系统,在rbac组件中它的作用是:
a、让未登录的用户无法访问相应的URL地址。 (用户登录之后 才能拥有特定权限,并且把相关权限格式化成字典格式 存入session)
b、把当前登录的用户权限和当前URL匹配 是否有权限,如果没有就返回404。
-
view视图层(view)
处理:路由系统分配的请求。
-
HTML层(前端页面显示)
前端显示页面(users.html)页面的时候,继承了模板页面(extends “layout.html” ),页面“ layout.html ”导入了{% load rbac %}。在rbac组件中templatetags文件下的rbac.py:@register.inclusion_tag。
在templatetags文件下的rbac.py文件内容中已经把用户相关权限格式化成menu_result,渲染到了rbac下面的menu.html文件里面。在menu.html里面已经根据code判断是是否显示相关的权限。
- 整个流程如下图:
Rbac组件的基本目录结构:
按照写的流程,来讲解rbac组件中的各个部分,以及功能,
- models数据库表设计(models.py)。
为了在前端页面实现 2方面的控制,还需要引入两个表菜单 menu和分组 group:
- 在一个页面,当前用户的权限,例如是否显示添加按钮、编辑、删除等按钮。
- 左侧菜单栏的创建。所以一共是5个类,7张表。
# models.py
from django.db import models
class Menu(models.Model):
'''页面中的菜单名'''
title = models.CharField(max_length=32)
class Group(models.Model):
'''权限url所属的组'''
caption = models.CharField(verbose_name='组名称',max_length=32)
menu =models.ForeignKey(verbose_name='组所属菜单',to='Menu',default=1) # 组所在的菜单
class Meta:
verbose_name_plural = 'Group组表'
def __str__(self):
return self.caption
class User(models.Model):
"""
用户表
"""
username = models.CharField(verbose_name='用户名',max_length=32)
password = models.CharField(verbose_name='密码',max_length=64)
email = models.CharField(verbose_name='邮箱',max_length=32)
roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
class Meta:
verbose_name_plural = "用户表"
def __str__(self):
return self.username
class Role(models.Model):
"""
角色表
"""
title = models.CharField(max_length=32)
permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
class Meta:
verbose_name_plural = "角色表"
def __str__(self):
return self.title
class Permission(models.Model):
"""
权限表
"""
title =