认证:判断用户是否登陆,从而获取用户的信息

权限:判断当前用户是否有权限访问API接口,例如:普通用户,管理员,超级管理员权限可能是不同的

下面通过案例进行介绍

模型类

from django.db import models


class UserInfo(models.Model):
    role_choices = ((1, "普通用户"), (2, "管理员"), (3, "超级管理员"),)
    role = models.IntegerField(verbose_name="角色", choices=role_choices, default=1)
    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)

权限类

from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    message = {'code': 1000, 'data': '无权访问'}

    def has_permission(self, request, view):
        if request.user.role == 2:
            return True
        return False

    
    def has_object_permission(self, request, view, obj):
        return True

在自定义的权限类中继承BasePermission

  • has_permission:定义权限判断逻辑

  • has_object_permission:检查某个用户是否对数据库中数据是否有操作权限

    • RetrieveModelMixin

    • UpdateModelMixin

    • DestroyModelMixin

  • message:在权限不同过时返回个前端数据

订单视图类

 

class OrderView(APIView):
    permission_classes = [MyPermission, ]

    def get(self, request, *args, **kwargs):
        print(request.user)
        print(request.auth)
        return Response({
            'code': 0,
            'data': '订单数据'
        })
  • 在视图类中设置类变量 permission_classes的值为 认证类 MyPermission,表示此视图在执行内部功能之前需要先经过权限校验。

  • 权限类是可以使用多个的,从上面中列表就可以知道

 

 

关于多个权限类

在开发中需要对用户进行多个权限的校验(都必须通过),可以使用多个权限类

当我们使用了多个权限类时,会按照列表顺序,逐个执行权限类的has_permission 方法,如果返回True则执行下一个权限类,如果返回None或者False,则抛出权限异常并停止权限校验

 目前从源码中我们知道权限是且的关系,即所有的权限类通过才能执行视图函数,如果我们希望是或的关系,该如何实现呢,其实只要重写 check_permissions函数即可,如下

 

        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 permission.has_permission(request, self):
                return

        self.permission_denied(
            request,
            message=getattr(permission, 'message', None),
            code=getattr(permission, 'code', None)
        )

 

 

全局配置

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES":["xxxx.xxxx.xx.类名","xxxx.xxxx.xx.类名",]
}

 

底层源码实现

 

 

关于has_permission的返回值

  • 返回True:执行下一个权限验证类

  • 返回None或者False,抛出权限验证失败的异常

 

posted on 2022-11-15 10:48  阿明明  阅读(104)  评论(0编辑  收藏  举报