APIView的dispatch方法

 def dispatch(self, request, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        self.headers = self.default_response_headers  # deprecate?

        try:
            self.initial(request, *args, **kwargs)
# 分析:
# 下面由initial的分析方法,就是调用方法之前运行任何需要发生的操作

            # Get the appropriate handler method

request = self.initialize_request(request, args, *kwargs) 分析

 def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)

        return Request(
            request,
            parsers=self.get_parsers(),
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )
# 分析:
# 返回了一个Request实例化的对象,其中有request和authenticators方法,那么新的request也就可以点出这些方法。
# 这里的Request方法是从request.py中导入的
from rest_framework.request import Request

    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        self._request = request
        self.authenticators = authenticators or ()
# 分析:
# 将原生的request赋值给属性_request,如果在类里面想用原生的request,那就得 request._request。
# 还有这里的authenticators,上面实例化时传入了值authenticators=self.get_authenticators()。
    def get_authenticators(self):
        """
        Instantiates and returns the list of authenticators that this view can use.
        """
        return [auth() for auth in self.authentication_classes]
# 分析:
# 得到的是一个列表,列表里实例化并返回此试图可以使用的验证器列表。
# 所以我们可以在试图中定义一个列表,里面放入认证类的类型,执行时就会自定实例化
# 文章末尾给出用法

initial方法分析

    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)

        # Ensure that the incoming request is permitted
        self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)

# 在调用方法之前运行任何需要发生的操作,我们看到self.perform_authentication(request)
    def perform_authentication(self, request):
        """
        Perform authentication on the incoming request.

        Note that if you override this and simply 'pass', then authentication
        will instead be performed lazily, the first time either
        `request.user` or `request.auth` is accessed.
        """
        request.user
# 分析 request已经是加工之后的request了,所以我们去request.py里找有没有user方法
    @property
    def user(self):
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

# 分析:
# 验证成功后返回通过验证的用户,可以通过下面的方法获得
    @user.setter
    def user(self, value):
        self._user = value
        self._request.user = value

认证组件的用法:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import exceptions
# Create your views here.

class MyAuth():
    def authenticate(self,request):
        token = request._request.GET.get('token')
        if not token:
            raise exceptions.AuthenticationFailed('用户认证失败')
        return ('wython',None)

    def authenticate_header(self,val):
        pass
# 分析:
# 自定义个认证类,有两个方法authenticate和authenticate_header,并且authenticate_header需要传个参数。
class Index(APIView):
    authentication_classes = [MyAuth,]
    def get(self,request,*args,**kwargs):
        return Response('ok')

    def post(self,request):
        pass

或者继承BaseAuthentication

from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication


class MyAuth(BaseAuthentication):
    def authenticate(self,request):
        # 写一些认证的逻辑
        # print('认证类中的方法,只要配置了就会走')
        token = request.Get.get('token')
        token_obj = models.Token.objects.filter(token=token).first()
        if token_obj:
            # 没有值表示没有登录
            return token_obj.user,token_obj
        else:
            raise AuthenticationFailed('您没有登录')

class Index(APIView):
    authentication_classes=[MyAuth,]
    def get(self,request):
        return Response('ok')

全局使用

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["apps.service.auth.Authentication",]
}

局部使用

# 在试图里写入
authentication_classes=[MyAuth,]
# 禁用的话就直接写个空列表,就不会认证了
authentication_classes=[]