Django中RBAC的应用
什么是权限
说到权限管理,首先要了解,在网站中权限到底是什么?
在网站中,用户通过URL地址,进入网站的后端逻辑,从而对网站的数据库进行操作管理。如果想要让拥有操作管理权限的用户来完成,而没有权限的用户无法操作.
什么是RBAC
RBAC
是基于角色的访问控制(Role-Based Access Control
)在RBAC
中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便
RBAC
介绍
RBAC
认为授权实际上是Who
、What
、How
三元组之间的关系,也就是Who
对What
进行How
的操作,也就是“主体”对“客体”的操作。
Who:是权限的拥有者或主体(如:User,Role)。
What:是操作或对象(operation,object)。
How:具体的权限(Privilege,正向授权与负向授权)。
RBAC
生命周期
1、用户登陆验证
2、根据用户身份验证信息,获取用户的角色
3、通过用户所绑定的角色,获取这个角色绑定的所有权限,并去重
4、查询用户所访问的URL是否在角色的权限内,如果在,则继续访问,如果不在,拒绝访问
Django中应用RBAC
1、models.py
from django.db import models
class Permission(models.Model):
"""
用户的权限
"""
url = models.CharField(max_length=60)
title = models.CharField(max_length=30)
class Meta:
verbose_name = '权限表'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Role(models.Model):
"""
角色表
"""
name = models.CharField(max_length=30)
permission = models.ManyToManyField(to='Permission', blank=True, null=True)
class Meta:
verbose_name = '角色表'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class User(models.Model):
name = models.CharField(max_length=32)
passwd = models.CharField(max_length=64)
role = models.ManyToManyField(to='Role')
class Meta:
verbose_name = '用户表'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
2、数据库迁移与执行
python manage.py makemigrations
python manage.py migrate
3、views.py
from django.views import View
from django.http import HttpResponse
from .models import *
# Create your views here.
class LoginView(View):
def post(self, request):
# 获取网页提交数据
username = request.POST.get('username')
password = request.POST.get('password')
# 通过网页提交数据,获取数据库中用户对象
user = User.objects.filter(name=username, passwd=password).first()
# 判断用户是否存在
if user: # 如果用户存在,存入权限列表,存入用户的id
# 通过获取到的用户对象,获取用户的权限列表
permissions = user.role.all().values("permission__url")
# 用列表推导式获取[{'permission__url': '/users/'}] 的value
permission_list = [item['permission__url'] for item in permissions]
# 把permission_list存入session中
request.session["permission_list"] = permission_list
# 把用户id存入session中
request.session['user_id'] = user.pk
return HttpResponse('登陆成功')
else:
return HttpResponse('登陆失败')
4、中间件方法来添加权限验证
django中间件:在django中,在进入视图函数之前,会先经过中间件,如果想在执行views之前或者之后做一些操作,可以使用django的中间件来完成
在app目录下添加middleware.py文件,写入以下内容
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
class ValidPermission(MiddlewareMixin):
"""
权限验证中间件
"""
def process_request(self, request):
# 当前访问路径
current_path = request.path_info
print(current_path)
# 检查是否属于白名单
valid_url_list=["/app01/login/","/reg/","/admin/.*"]
# 如果访问的当前路径在名单中
if current_path in valid_url_list:
return None
# 校验是否登录
user_id=request.session.get("user_id")
if not user_id:
return redirect("/login/")
# 校验权限
permission_list = request.session.get("permission_list",[])
if current_path in permission_list:
return None
else:
return HttpResponse("没有访问权限!")
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
1、process_request(self,request)
2、process_view(self, request, callback, callback_args, callback_kwargs)
3、process_template_response(self,request,response)
4、process_exception(self, request, exception)
5、process_response(self, request, response)
以上方法返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户
5、在settings.py中添加自定义的中间件方法
MIDDLEWARE = [
'app01.middleware.ValidPermission', # 自定义中间件
]