drf框架中的权限认证组件

2023年 9月 28日 54.6k 0

之前讲过了用户认证组件,在此基础上,我们说一下权限认证组件,其主要用途是要让不同的人拥有不同的访问权限。
首先我设计了三个不同的身份来作为示例

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({"成功获取权限"})

这就是大概得权限认证的写法。有问题可以在下方留言

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论