Проверка прав: Permissions

Определение
Для управления правами доступа в DRF есть встроенные классы, они называются permissions.

Права доступа проверяются при получении запроса, одновременно с аутентификацией: система определяет, достаточно ли у пользователя прав на выполнение запрошенных операций.



Настроить права доступа можно на уровне всего проекта или на уровне отдельных классов и функций. Устанавливаются глобальные ограничения на уровне проекта, а при необходимости ограничения ослабляются на уровне классов или функций.

Ссылка на документацию
Установка ограничений на уровне проекта
В словаре настроек REST_FRAMEWORK задают параметр DEFAULT_PERMISSION_CLASSES.

Уровни доступа:

  • AllowAny — всё запросы разрешены, для всех пользователей.
  • IsAuthenticated — только аутентифицированные пользователи могут выполнить любой запрос.
  • IsAuthenticatedOrReadOnly — аутентифицированные пользователи могут выполнить любой запрос. Анонимные могут делать запросы на чтение. Аутентифицированные могут делать запросы на создание, удаление или редактирование информации.
  • IsAdminUser — выполнение запросов запрещено всем, кроме администратора.
  • DjangoModelPermissions - авторизация будет предоставлена только в том случае, если пользователь прошел проверку подлинности и ему назначены соответствующие разрешения в модели.
  • DjangoModelPermissionsOrAnonReadOnly - Аналогичен DjangoModelPermissions, но также позволяет пользователям, не прошедшим проверку подлинности, иметь доступ к API только для чтения.
  • DjangoObjectPermissions - Этот класс разрешений связан со стандартной структурой разрешений объектов Django, которая описывает разрешения для отдельных объектов в моделях.
Настройки файла settings.py

REST_FRAMEWORK = {
    ...
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated', 
    ],
УСТАНОВКА ОГРАНИЧЕНИЙ НА УРОВНЕ запроса
Для указания ограничения на уровне класса необходимо указать атрибут permission_classes в теле. Его значение будет равно объекту из модуля permissions пакета rest_framework
Файл views.py

from rest_framework.permissions import IsAuthenticatedOrReadOnly

...

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer
    permission_classes = (IsAuthenticatedOrReadOnly,) 
УСТАНОВКА ОГРАНИЧЕНИЙ НА УРОВНЕ объекта
Часто встречается ограничение доступа до запросов с объектами, созданными пользователями. Например, удалить пост может только автор поста.

В Django REST Framework все классы разрешений наследуются от базового класса BasePermission. В нем описаны два метода:

  • в методе has_permission определяются разрешения на уровне запроса;
  • в методе has_object_permission устанавливаются разрешения на уровне объекта.
Доступ будет разрешен, если методы вернут True. Для создания собственных разрешений — необходимо описать класс, расширяющий BasePermission и переопределить один или оба его метода. Создавать классы принято в отдельном файле permissions.py
Файл permissions.py

from rest_framework import permissions

class PersonOrReadOnly(permissions.BasePermission):

    def has_permission(self, request, view):
        return (request.method in permissions.SAFE_METHODS
                   or request.user.is_authenticated)

    def has_object_permission(self, request, view, obj):
        return obj.person == request.user 
Ограничения
  • Метод has_object_permission не выполняется для представлений, возвращающих коллекции объектов или создающих новый объект модели (поскольку объект ещё не существует).
  • Метод has_object_permission вызывается только в том случае, если метод has_permission вернул True.
  • По умолчанию оба метода возвращают значение True. Окончательное решение о доступе будет зависеть от результата работы того метода, который был переопределён.
Подключение класса к отображению

from .permissions import PersonOrReadOnly

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer
    permission_classes = (PersonOrReadOnly,