之前讲过了用户认证组件,在此基础上,我们说一下权限认证组件,其主要用途是要让不同的人拥有不同的访问权限。
首先我设计了三个不同的身份来作为示例
from django.db import models
# Create your models here.
class Userinfo(models.Model):
role=models.IntegerField(verbose_name="角色",choices=((1,"总监"),(2,"经理"),(3,"员工")),default=3)
username=models.CharField(verbose_name="用户名",max_length=32)
password=models.CharField(verbose_name="密码",max_length=64)
token=models.CharField(verbose_name="token信息",max_length=64,null=True,blank=True)
同用户认证组件,我们先从as_view()函数入手,来到dispatch中的initlal函数
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
然后进入到第17行,这个是关于认证组件的相关认证
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
先给大家看看我的代码
class UserPermission(BasePermission):
message=[{'status':False,"msg":"员工无权访问"}]
def has_permission(self, request, view):
if request.user.role==3:
return True
return False
class ManagerPermission(BasePermission):
message=[{'status':False,"msg":"管理员无权访问"}]
def has_permission(self, request, view):
if request.user.role==2:
return True
return False
class BossPermission(BasePermission):
message=[{'status':False,"msg":"总监无权访问"}]
def has_permission(self, request, view):
if request.user.role==1:
return True
return False
我们继承了BasePermission对象,里面就要求我们重写相关方法,我们在check_permission函数中
就看到如果我们的has_permission方法没有返回True,那么就说明没有权限,会执行相关的报错函数,这里的message就是我们的报错信息,所以我们在自定义权限认证的时候,可以通过更改message里面的内容实现自定义错误
但是这个地方如果你有一个条件没有满足权限,那么他就没有权限,就好比这个人既要有boss的权限,也要有管理员的权限,这种关系有时候不是我们现实情况所需要的,有时候我们访问某个资源,只要含有其中一个权限就行了,而不是满足所有权限,那么怎么办呢。 我们可以重写一下方法
from rest_framework.views import APIView
class NbApiView(APIView):
def check_permissions(self, request):
nopermission_object=[]
for permission in self.get_permissions():
if permission.has_permission(request, self):
return
else:
nopermission_object.append(permission)
else:
self.permission_denied(
request,
message=getattr(nopermission_object[0], 'message', None),
code=getattr(nopermission_object[0], 'code', None)
)
这样就会执行我们所想要执行的check_permission方法,当然,我们在继承时,需要继承我们写的类,列入下面的代码
class OrderView(NbApiView):
# 总监和管理者可以访问
permission_classes = [BossPermission, ManagerPermission]
# 重写check_permissions
# 让满足任意一个权限即可通过
# 报错的话从没过验证列表的第一个位置的message和code进行获取,直接拿即可
def check_permissions(self, request):
nopermission_object=[]
for permission in self.get_permissions():
if permission.has_permission(request, self):
return
else:
nopermission_object.append(permission)
else:
self.permission_denied(
request,
message=getattr(nopermission_object[0], 'message', None),
code=getattr(nopermission_object[0], 'code', None)
)
def get(self,request):
return Response({"成功获取权限"})
这就是大概得权限认证的写法。有问题可以在下方留言