06 drf源码剖析之权限

Posted liubing8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06 drf源码剖析之权限相关的知识,希望对你有一定的参考价值。

06 drf源码剖析之权限

1. 权限简述

  • 权限与身份验证和限制一起,决定了是否应授予请求访问权限。
  • 权限检查始终在视图的最开始处运行,然后再允许执行其他任何代码。权限检查通常会使用request.userrequest.auth属性中的身份验证信息来确定是否应允许传入请求。
  • 权限用于授予或拒绝不同类别的用户对API不同部分的访问。

2. 权限使用

  • 自定义权限认证类

    from rest_framework.permissions import BasePermission
    from rest_framework import exceptions
    
    class MyPermission(BasePermission):
        message = {'code': 10001, 'error': '你没权限'}
        def has_permission(self, request, view):
            """
            Return `True` if permission is granted, `False` otherwise.
            """
            if request.user:
                return True
    
            # raise exceptions.PermissionDenied({'code': 10001, 'error': '你没权限'})
            return False
    
        def has_object_permission(self, request, view, obj):
            """
            Return `True` if permission is granted, `False` otherwise.
            """
            return False
  • 在需要权限认证的类中加permission_classes

    class OrderView(APIView):
        permission_classes = [MyPermission,]
        def get(self,request,*args,**kwargs):
            return Response('order')
    
    
    class UserView(APIView):
        permission_classes = [MyPermission, ]
        def get(self,request,*args,**kwargs):
            return Response('user')

3.源码剖析

  • 请求过来先执行dispatch方法

    class APIView(View):
        permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    
        def dispatch(self, request, *args, **kwargs):
            # 封装request对象...
            self.initial(request, *args, **kwargs)
            # 通过反射执行视图中的方法...
  • initial方法过渡

      def initial(self, request, *args, **kwargs):
            # 版本的处理...
            # 认证...       
            # 权限判断
            self.check_permissions(request)
    
            self.check_throttles(request) # 节流...
  • check_permissions方法,依次对权限类对象认证权限

    def check_permissions(self, request):
        # [对象,对象,]
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
                self.permission_denied(request, message=getattr(permission, 'message', None))
  • get_permissions方法,将权限类实例化成对象列表

    def get_permissions(self):
        return [permission() for permission in self.permission_classes]
  • 执行自定义权限类的has_permission方法,判断有无权限

    class MyPermission(BasePermission):
        def has_permission(self, request, view):
            if request.user:
                return True
            return False

4. 总结

  1. 当用户请求过来时,先执行dispatch方法,通过initial方法执行check_permissions方法
  2. 找到权限的所有类并实例化成对象列表
  3. 循环该实例化对象列表,执行每个对象的has_permission方法
  4. 返回True和False进行权限的认证,可定制错误信息

以上是关于06 drf源码剖析之权限的主要内容,如果未能解决你的问题,请参考以下文章

05 drf源码剖析之认证

DRF权限

我瞅瞅源码系列之---drf

DRF认证

DRF认证 -- 2019-08-08 18:02:57

django rest_fremework源码之权限流程剖析