Implementation of django Authentication Class Configuration

  • 2021-12-12 09:05:57
  • OfStack

Directory 1. Configure authentication classes 1. Authenticate the global profile
STEP 2 Use locally
3. Anonymous user configuration:
2. Built-in authentication class 1.BaseAuthentication
2. Other certification categories
3. Summary 1. Custom authentication classes:
2. Authentication configuration:
3. Source code flow:

1. Configure authentication classes

1. Authenticate the global profile

After the source code process analysis of authentication, the authentication of DRF is configured globally in api_setting, and the following is the source code of api_setings:


api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

def reload_api_settings(*args, **kwargs):
    setting = kwargs['setting']
    if setting == 'REST_FRAMEWORK':  # In the project settings.py Adj. key
        api_settings.reload()

setting_changed.connect(reload_api_settings)

Which references django, REST_FRAMEWORK in settings. py as key as the configuration, so the global configuration example:


# Global authentication configuration 
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',]   # The path of the class in which authentication is written, not in the views In, I put it here utils Directory auth.py Medium 
}

STEP 2 Use locally

If some view does not require authentication, add authentication_classes= [] to the view class


authentication_classes = []    #authentication_classes Is empty, indicating that authentication is not required 

3. Anonymous user configuration:


REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',] ,   # The path of the class in which authentication is written, not in the views In, I put it here utils Directory auth.py Medium     "UNAUTHENTICATED_USER": lambda:" Anonymous " , # Anonymous user configuration, only the corresponding return value of the function or class is required, corresponding to request.user=" Anonymous "
"UNAUTHENTICATED_token": None , # Anonymous token Only the corresponding return value of the function or class is required, corresponding to the request.auth=None
}

2. Built-in authentication class

1.BaseAuthentication

BaseAuthentication is django rest framework provides us with the most basic authentication class, just like the source code flow 1, the two methods defined in this class, authenticate and authenticate_header (response header returned by authentication failure), are rewritten for authentication when used, as in the example:


class BaseAuthentication(object):
    """
    All authentication classes should extend BaseAuthentication.
    """def authenticate(self, request):
        """
        Authenticate the request and return a two-tuple of (user, token).
        """raise NotImplementedError(".authenticate() must be overridden.")

    def authenticate_header(self, request):
        """
        Return a string to be used as the value of the `WWW-Authenticate`
        header in a `401 Unauthenticated` response, or `None` if the
        authentication scheme should return `403 Permission Denied` responses.
        """pass

2. Other certification categories


## Path :rest_framework.authentication
BasicAuthentication  # Authentication based on browser 
SessionAuthentication # Based on django Adj. session Carry out certification 
RemoteUserAuthentication # Based on django admin Authentication of users in, which is also an example of official website 
TokenAuthentication # Based on drf Internal token Certification 

3. Summary

1. Custom authentication classes:

Inherit BaseAuthentication, override authenticate method and authenticate_header (pass is fine), and authenticate () method needs three cases (return ancestor, exception, return none).

2. Authentication configuration:


# Global authentication 
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',]
}

# Local authentication 
authentication_classes = [BaseAuthentication,]

# Is a view not authenticated 
authentication_classes =[]

3. Source code flow:

1. In django (CBV), the incoming request from the client executes the as_view method of the view class, while in as_view method, the dispacth method is executed, and then the corresponding method is executed according to the type (reflection) of the request (get, post, etc.).

2. Using the view class in django rest framework needs to inherit APIView. When a request arrives at the view class, the as_view method of the view class will be executed, while there is no as_view () method in OrderView, so the as_view () method of APIView will be executed.

3. From the source code of APIView, we can see that as_view in APIView executes the as_view method of the parent class. When we look at the parent class of APIView, it is View class, which happens to be the view view class in django.

4. From the source code of View, we can see the execution flow of as_view () method of View class: validate the request method-- > Returns the name of the view function (the view function executes the dispatch method), 1 when a request comes in to execute the view function-- > Execute the dispatch method

5. When the as_view method of APIView executes the as_view method of the parent class, the request will execute the view method, the dispatch method will be executed in the view method, and the Oderview does not have the dispatch method, so the dispatch method of the parent class (APIView) will be executed.

6. From the source code analysis of APIView, when executing dispatch method of APIView, self.initialize_request method will be executed, which will encapsulate the original request of django.

7. self.initialize_request () source code analysis, instantiate Request () class, encapsulate the original request, authenticators (authentication), execute self.get_authenticators (), and then start the authentication process of django rest framework

8. self.get_authenticators () source code analysis, using list generation, circulating self.authentication_classes, instantiating every one of them, returning to the list, it is not difficult to find that authentication_classes attribute is formal. We use the authentication class list when authenticating, and this attribute will be automatically searched for authentication here. What if our view class does not define an authentication method? Of course, django rest framework has added the default configuration to us. If we don't define it, DEFAULT_AUTHENTICATION_CLASSES in settings will be automatically used as the default (global).

9. Continue to analyze the dispatch method of APIView. At this time, execute the self. inital method and pass the encapsulated request object (Reuqest) as a parameter.

10. self.perform_authentication method is executed in self.perform_authentication method, while request. user is executed in self method. request is an Request object, so it is necessary to analyze user attribute in Request class.

11. From source analysis, in the Request object, the user property is a property method and executes the self._authentication method,

12. From the source code analysis, self. authenticators is looped in self._authentication of Request object (the list is composed of authentication objects [Object 1, Object 2]), and authenticate method in each object is executed to return tuple. At the same time, exception capture is carried out in this process, and exceptions will be returned to users. The following is exception verification logic:

If there is an exception, execute the self. _not_authenticated () method and continue to throw the exception up.
If there is a return value that must be 1 tuple, assign values to self. user, self. auth (request. user and request. auth), and jump out of the loop.
If None is returned, it is processed by the next loop. If both are None, self._not_authenticated () is executed, returning (AnonymousUser, None)
13. When there is no return value, self._not_authenticated () is executed, which is equivalent to anonymous user and has not passed authentication. At this time, django will return the default anonymous user setting AnonymousUser. If it is necessary to set the anonymous user return value separately, write the return value of UNAUTHENTICATED_USER:

14. Therefore, after the above analysis, when we need to authenticate, we need to define authenticate in every authentication class for authentication, and we need to return to the ancestor.


Related articles: