This section describes rights management

Django_rest_frame permission management requires a combination of two things :authentication_classes and permission_classes, whether you use the REST framework as a class or as a decorator in Django views

# Method 1: Decorator
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response


@api_view(["GET", ])
@permission_classes([AllowAny,])
@authentication_classes([SessionAuthentication, BasicAuthentication])
def test_example(request):
    content = {
            'user': unicode(request.user),  # `django.contrib.auth.User` instance.
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Method 2: Class
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    permission_classes = (AllowAny,)

    def get(self, request, format=None):
        content = {
            'user': unicode(request.user),  # `django.contrib.auth.User` instance.
            'auth': unicode(request.auth),  # None
        }
        return Response(content)
Copy the code

The above is the default permission configuration scheme. There is no difference between write and no write. The REST framework has its own Settings file, where the original defaults can be found:

Project Settings file

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'your_authentication_class_path',),... }Copy the code

In the REST Settings file, when obtaining properties, the project Settings file will be loaded first, if the project does not have the default Settings to load their own:

  • Initialize the API_settings object
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
Copy the code
  • APISettingsClass to retrieve attributes from the project’s Settings file firstREST_FRAMEWORKObject value, if not find their own default value
@property
def user_settings(self):
    if not hasattr(self, '_user_settings') :# _user_settings Defaults to loading the REST_FRAMEWORK object in the project Settings file
        self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
    return self._user_settings

def __getattr__(self, attr):
    if attr not in self.defaults:
        raise AttributeError("Invalid API setting: '%s'" % attr)

    try:
        # Check if present in user settings
        User_settings is the project's Settings file. If not, use default
        val = self.user_settings[attr]
    except KeyError:
        # Fall back to defaults
        val = self.defaults[attr]

    # Coerce import strings into classes
    if attr in self.import_strings:
        val = perform_import(val, attr)

    # Cache the result
    self._cached_attrs.add(attr)
    setattr(self, attr, val)
    return val
Copy the code

In Settings, you can automatically detect changes in the project Settings and reload your configuration file:

A brief analysis of the principle of authority management

How does the REST framework use authentication_classes and permission_classes and combine them for permission management?

  • When implemented using classes, we use the REST framework’s APIVIEW, either directly or indirectly, inurls.pyClass used inas_viewMethod to build the router
# views.py
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated


class ExampleAPIView(APIView):
    permission_classes = (IsAuthenticated,)
    ...
    
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
from django.conf.urls import url, include

from .views import ExampleAPIView

urlpatterns = [
    url(r'^example/(? P
      
       [-\w]+)/examples/? $'
      ,
        ExampleAPIView.as_view()),
]

Copy the code
  • When we call apiView.as_view (), the class calls its parent’s method of the same name:

  • In the parent class’s method of the same name, the dispatch method is called:

  • Rest overrides this method to do a server-side initialization (adding validation information, etc.) on requsET

    Invoking permission Management

Authentication is done using either the default or the permission authentication you specify in permission management: here you just do the authentication and store the result, and once you’re done authentication_classes is done. The validation results will be used in the permission_classes specified later!

    def get_authenticators(self):
        """ Instantiates and returns the list of authenticators that this view can use. """
        return [auth() for auth in self.authentication_classes]
Copy the code

Determines whether the current interface has access to the specified permission_classes:

class IsAuthenticatedOrReadOnly(BasePermission):
    """ The request is authenticated as a user, or is a read-only request. """

    def has_permission(self, request, view):
        return (
            request.method in SAFE_METHODS or
            request.user and
            request.user.is_authenticated
        )
Copy the code

Finally, whether or not you use permission_classes to determine access, the default or your own specified authentication_classes will be executed and put the permission results in the request!