RBAC(Role-based Access Control)
在Django中的应用:
首先理解Django的生命周期
1、当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
2、url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
3、视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
4、客户端浏览器接收到返回的数据,经过渲染后显示给用户。
RBAC在Django中的使用原理:
1、首先用户第一次在浏览器中登录时,将其相关的所有权限写入session中(session中同时还能保留用户的其他信息,比如生成菜单界面的信息等),此步骤亦可称之为用户权限的初始化(发生在django的中间件process_request方法里)。
2、在用户再次登录时,请求将在中间件中进行判断,通过正则表达式来匹配session中保存的权限,如果匹配成功,再根据用户的不同权限,进行不同的页面功能展示。
权限表结构
from django.db import models
# Create your models here.
class Role(models.Model):
title = models.CharField(max_length=32,verbose_name="角色")
permissions = models.ManyToManyField(to="Permission",verbose_name="拥有权限的角色",blank=True) #权限和角色是多对多的关系
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "角色表"
class Permission(models.Model):
title = models.CharField(max_length=32,verbose_name="权限名")
url = models.CharField(max_length=32,verbose_name="带正则的url")
codes = models.CharField(max_length=32,verbose_name="代码")
group = models.ForeignKey(to="Group",verbose_name="所属组",blank=True) #组和权限是一对多的关系,一个组有多个权限
menu_gp = models.ForeignKey(to='Permission',related_name='aaa',null=True,blank=True,verbose_name="组内菜单")
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "权限表"
class UserInfo(models.Model):
name = models.CharField(max_length=32,verbose_name="姓名")
password = models.CharField(max_length=64,verbose_name="密码")
email = models.CharField(max_length=32,verbose_name="邮箱")
roles = models.ManyToManyField(to="Role",blank=True) #用户和角色是多对多的关系
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "用户表"
class Group(models.Model):
title = models.CharField(max_length=32,verbose_name="组名称")
menu = models.ForeignKey(to="Menu",verbose_name="组内菜单",blank=True) #一个组下有多个菜单
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "权限组"
class Menu(models.Model):
caption = models.CharField(max_length=32,verbose_name="菜单")
def __str__(self):
return self.caption
class Meta:
verbose_name_plural = "菜单表"
五个类,七张表:
角色表,用户表,权限表,权限组组表,菜单表:
角色表和权限表是多对多的关系(一个角色可以有多个权限,一个权限可以对应多个角色)
用户表和角色表是多对多的关系(一个用户可以有多个角色,一个角色有多个用户)
所以有会多生成两张关系表
一个菜单下面有多个组
一个组下面有多个菜单
一个菜单下面有多个权限
需要注意的点:
1、有些URL不需要权限判断,例如一些登录后能看到的公共界面,所以可以加入白名单。
2、不同的用户,对于增删改查有不同的权限,精确到粒度级别。
3、可以用到面向对象中的封装进行控制页面的按钮是否展示。
网友评论