This is the 14th day of my participation in the More text Challenge. For more details, see more text Challenge

Django authentication has three methods, the third custom method is used here

Method 1 System session authentication

Rest_framework. Authentication. SessionAuthentication ajax requests through certification: cookies to carry sessionid, csrftoken, to carry the x - csrftoken request headerCopy the code

Method 2 JWT authentication

Rest_framework_jwt. Authentication. JSONWebTokenAuthentication ajax requests through the authentication, to carry the authorization request header, value of JWT Spaces tokenCopy the code

Method 3 (common) customization: based on JWT, others

1) Custom authentication class, inheriting BaseAuthentication(or a subclass), Rewrite authenticate 2) Complete in authenticate get the authentication id auth Reverse parse out the user user If the first two operations fail return None => Tourist If the first two operations succeed return user, auth => Login user Note: If an exception is thrown on a branch and the direct definition fails => Invalid userCopy the code

1 process

1.1 Source Content

  1. When the user logs in, the login class is runas_view()Method, enterAPIViewOf the classdispatchmethods
  2. performself.initialize_requestThis method, it’s encapsulated insiderequestAnd the list of authentication objects
  3. performself.initialIn the methodself.perform_authenticationIt’s runningusermethods
  4. To perform theuserMethod insideself._authenticate()methods

1.2 Custom Methods

  1. Then execute the class defined by yourselfauthenticateMethod that the class defines itself inheritsBaseAuthenticationClass, which hasauthenticateMethod, if not in the class you defineauthenticateMethod will report an error
  2. From theauthenticateThe user and auth values obtained by the method are assigned to the user and auth methods
  3. These two methods assign the values of user and auth torequest.user: is the object of the login user.request.auth: is the authentication information dictionary

2 the return value

  • Without authentication information, return None => tourist
  • There is authentication information, verification is successful, return a tuple, the first parameter assigned torequest.user, the second is assigned torequest.auth
  • If there is authentication information, the verification fails, and an exception is thrown => Unauthorized user

3 Source code introduction

# The APIView dispatch has self. Initialize_request, which returns a Request class,It encapsulates django's request, list of authentication objects, and other parametersclass APIView(View) :
    # 1. Enter the Dispatch method of the APIView class
    def dispatch(self, request, *args, **kwargs) :

        self.args = args
        self.kwargs = kwargs
        # 2. Execute self.initialize_request, encapsulating request and authentication object list with other parameters
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            Self. initial; self.perform_authentication; self.initial
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)
            
     # 2. Execute self.initialize_request, encapsulating request and authentication object list with other parameters
     ''' def initialize_request(self, request, *args, **kwargs): parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), # [MyAuthentication(),] negotiator=self.get_content_negotiator(), parser_context=parser_context ) '''
        
    Self. initial; self.perform_authentication; self.initial
    ''' def initial(self, request, *args, **kwargs): self.format_kwarg = self.get_format_suffix(**kwargs) neg = self.perform_content_negotiation(request) Request. Accepted_renderer, request. Accepted_media_type = neg scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, Scheme # Authentication permission throttling three brothers self.perform_authentication(request) self.check_permissions(request) self.check_throttles(request) ' ' '
    
    Self. initial; self.perform_authentication; self.initial
    def perform_authentication(self, request) :
        request.user
        
        
    # 4: Self._authenticate () is executed in user method
    @property
    def user(self) :
        """ Returns the user associated with the current request, as authenticated by the authentication classes provided to the request. """
        if not hasattr(self, '_user') :with wrap_attributeerrors():
                self._authenticate()
        return self._user
Copy the code

4 use

Method one: rewrite the native methods BaseAuthtication. Authenticate

Create an authentication class that extends BaseAuthentication and implements the authenticate method

util/auth.py

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


class Authtication(BaseAuthentication) :
    Commonly used #
    def authenticate(self,request) :
        token = request._request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).fitst()
        if not token_obj:
            raise exceptions.AuthenticationFailed('User authentication failed')
            
        Within the REST Framework, the entire two fields will be assigned to the request for subsequent use
        return (token_obj.user, token_obj)

    This method is usually not used
    def authenticate_header(self, request) :
        pass
Copy the code

5 introduced

5.1 Partial Use

from rest_framework.views import APIView
from apps.api.auth import Authtication

class UserInfoView(APIView) :
    
    # Authenticate this view alone
    authentication_classes = [Authtication,]
    def get(self, request, *args, **kwargs) :
        print(request.user)
        return HttpResponse('User Related Information')
Copy the code

5.2 Using setting.py globally

REST_FRAMEWORK = {
    # Global configuration
    # 'DEFAULT_AUTHENTICATION_CLASSES': ['apps.api.utils.auth.FirstAuthtication', 'apps.api.utils.auth.Authtication'],
    'DEFAULT_AUTHENTICATION_CLASSES': ['apps.api.utils.auth.Authtication'].# anonymous, request.user = None
    'UNAUTHENTICATED_USER': None.# anonymous, request.auth = None
    'UNAUTHENTICATED_TOKEN': None,}Copy the code