[PYTHON] Since there is no Japanese explanation around Permission of Django REST Framework, I wrote it

Why i thought to write

I like Django and I'm touching it privately, but there are few articles around Django REST Framework (DRF) on Qiita even if it is as it is ... (At the stage of writing this article) 159 cases) It's a very powerful framework, and it's becoming more common to develop front-end and server-side separately, so I think DRF is one of the most attractive options. On the other hand, there are few articles and technical books in Japanese, and if it becomes essential to read English documents, I think that it will give an impression that it is difficult for people who can not speak English. Especially, I wrote it because I think that it tends to be written in English that even beginners can not understand even in Japanese.

DRF Permission

This is an area related to access control.

Authentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization. Apple Developer Documentation

As the Apple developer documentation suggests, authentication and identification alone are generally not enough to access information and code, and the idea is that the entity requesting access needs permissions.

This DRF Permission is executed at the start of the view, and permission checks typically use the credentials of the request.user and request.auth properties to determine whether to allow the request.

How to determine authority

DRF permissions are always defined as a list of permission classes.

Each permission in the list is checked before executing the body of view, and if it fails, an exception of ʻexceptions.PermissionDenied` is thrown and the body is not executed.

DRF permissions also support object-level permissions, which are used to determine whether a user is allowed to work on a particular object (usually a model).

If you create your own view and apply object-level permissions to it, or if you want to override the method in the get_object generic view, use the view method when you get the.check_object_permissions (request, obj)view. Must be called.

This will continue if the view has the appropriate permissions, and will return a PermissionDenied or NotAuthenticated exception if you don't have the permissions.

Setting method

The default authorization policy settings are set using DEFAULT_PERMISSION_CLASSES.

settings.py


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

If not specified, use ʻAlloWAny`.

settings.py


REST_FRAMEWORK = {
   'DEFAULT_PERMISSION_CLASSES': (
      'rest_framework.permissions.AllowAny',
   )
}

You can also set the authentication range for each view and each viewset using the APIView class-based view.

views.py


from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)

Another way to write it is if you're writing a function-based view using the @api_view decorator.

views.py


@api_view('GET')
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)

API reference

AllowAny

The AllowAny class allows unlimited access whether the request is authenticated or not. Using an empty list or tuple to set permissions will give similar results, so it's not strictly necessary, but it's useful for explicit intent.

IsAuthenticated The IsAuthenticated class denies any unauthenticated user and grants any other privileges. It is used to make it accessible only to users who have registered with the API.

IsAdminUser The IsAdminUser class denies all users except when ʻuser.is_staff is True`.

IsAuthenticatedOrReadOnly The IsAuthenticatedOrReadOnly class allows an authenticated user to make any request. Requests from unauthorized users are limited to cases where the request method is a secure method such as GET, HEAD or ʻOPTIONS`.

It is suitable when you want to grant read permission to anonymous users with API and write permission to authenticated users.

DjangoModelPermissions DjangoModelPermissions is tied to the Django standard model django.contrib.auth permissions. It should only be applied to views that have the .queryset property set and will be approved if the user is authenticated and assigned the relevant model permissions. As an example,

--The POST request requires the user to have permission on the ʻadd` model

--PUT and PATCH requests require permissions on the change model

--DELETE request requires permissions on the delete model

It has become.

You can also override the default behavior to support custom model permissions, for example view can include GET request permissions.

If you use the overridden get_query () method, it may not include the queryset attribute. In this case, it is recommended to mark the view with the required querset as shown below.

queryset = User.objects.none() #Required for DjangoModelPermissions

DjangoModelPermissionsOrAnonReadOnly Similar to the DjangoModelPermissions above, but here it allows unauthenticated users to have read-only access to the API.

DjangoObjectPermissions

It works with Django's standard object permission class, which allows per-object permissions for your model. If you want to use it, you need to add a permission backend that supports object-level permissions such as django-guardian.

Note that DjangoObjectPermissions doesn't require the django-guardian package, and other object-level backends need to be supported as well.

Similar to DjangoModelPermissions, this permission should only be applied to views with .queryset and will only be granted if the user has been authenticated and assigned model permissions associated with the object permissions. .. In addition, you can use custom model permissions by overriding'DjangoModelPermissions'.

TokenHasReadWriteScope It is intended to be used with either the ʻOAuthAuthentication or the ʻOAuth2Authentication class. Only secure methods such as GET, ʻOPTIONS or HEAD` are allowed if the authenticated token is assigned read permission.

Custom permissions

Implement custom permissions BasePermission can be implemented by overriding one or both of the following methods:

The method returns True if you want to assign access to the request, otherwise it returns False.

Also, if you need to test whether the request is a read or write operation, you can use GET, ʻOPTIONS, HEADfor constants that are tuples containingSAFE_METHODS` as follows: You need to check the request method like.

if request.method in permissions.SAFE_METHODS:
    # Check permissions for read-only request
else:
    # Check permissions for write request

reference

Django REST Framework

Recommended Posts

Since there is no Japanese explanation around Permission of Django REST Framework, I wrote it
Since memory_profiler of python is heavy, I measured it
Understand the benefits of the Django Rest Framework