Файлы
posts
migrations
__init__.py
0001_initial.py
models.py
serializers.py
__init__.py
apps.py
admin.py
urls.py
views.py
yatube_api
asgi.py
__init__.py
settings.py
urls.py
wsgi.py
manage.py
manage.py
Урок 1: Авторизация (проверка прав)
1 / 2
Установите обязательную аутентификацию на уровне всего проекта, а неаутентифицированным пользователям разрешите читать публикации.
В DEFAULT_PERMISSION_CLASSES словаря REST_FRAMEWORK установите общий уровень доступа.
В описании view-класса публикаций добавьте поле permission_classes и укажите в нём уровень доступа для неаутентифицированных пользователей.
Подумайте, как установить общий уровень аутентификации.
Браузер849x893
Браузер849x893

Авторизация (проверка прав)

При действующем уровне доступа к вашему API любой аутентифицированный пользователь может удалять и редактировать не только свои, но и чужие записи. Это неправильно.
В курсе Django вы применяли декоратор @login_required для ограничения доступа к определённым страницам проекта. В прошлом спринте вы узнали, как ограничить доступ к API для неаутентифициронных пользователей. Но и этого недостаточно.
Безопасность — важная часть любого сервиса, и если вы не настроите механизмы авторизации, любой пользователь получит полный доступ ко всем функциям API.
Самое время разобраться со встроенными разрешениями и настроить права доступа так, чтобы редактировать и удалять записи могли только их авторы.

Разрешения (Permissions)

При запросе к API одновременно с аутентификацией система определяет, достаточно ли прав у пользователя на выполнение запрошенных операций. Эта проверка выполняется в самом начале обработки запроса.
Настроить права доступа (или «пермишены», в таком виде этот термин тоже будет вам встречаться) можно на уровне всего проекта, на уровне отдельного приложения или даже на уровне отдельных классов.
Начнём с уровня проекта: будет надёжнее установить глобальные ограничения, а потом ослабить их там, где это необходимо.
Для установки ограничений на уровне проекта в словаре настроек REST_FRAMEWORK задайте параметр DEFAULT_PERMISSION_CLASSES
settings.py
Скопировать кодPYTHON
REST_FRAMEWORK = { ... 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], }
На уровне проекта можно установить один из четырёх вариантов доступа:
  • AllowAny — всё разрешено, любой пользователь (и даже аноним) может выполнить любой запрос.
  • IsAuthenticated — только аутентифицированные (зарегистрированные) пользователи имеют доступ к API и могут выполнить любой запрос.
  • IsAuthenticatedOrReadOnly — неаутентифицированные пользователи могут совершать запросы на чтение, но не могут ничего создавать, удалять или изменять.
  • IsAdminUser — только администраторы/суперпользователи могут делать запросы.
Чтобы настроить разрешения на уровне view-класса, импортируйте модуль permissions из пакета rest_framework и добавьте поле permission_classes в тело класса:
Скопировать кодPYTHON
class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

Создание собственных разрешений

Иногда возникает необходимость в написании собственных разрешений. Например, вы хотите, чтобы редактировать или удалять пост мог только администратор или автор, а всем прочим пользователям пост должен быть доступен только для чтения.
В Django REST Framework есть базовый класс BasePermission, от него наследуются все классы разрешений. Его методы принимают на вход:
  • объект запроса request: содержит все данные запроса
  • объект view: объект (класс или функция), к этому объекту можно обратиться, чтобы проверить какие-то поля или методы
  • объект obj: объект, права на доступ к которому проверяются
Этот класс применяют для ограничения доступа на уровне объектов. Доступ будет разрешён, если метод BasePermission вернёт True.
Скопировать кодPYTHON
class BasePermission(metaclass=BasePermissionMetaclass): """ A base class from which all permission classes should inherit. """ def has_permission(self, request, view): """ Return `True` if permission is granted, `False` otherwise. """ return True def has_object_permission(self, request, view, obj): """ Return `True` if permission is granted, `False` otherwise. """ return True
Чтобы создать собственное разрешение — опишите свой класс, расширяющий BasePermission и переопределите один из его методов.
Пример класса, который позволяет любые действия администратору, а больше никому:
Скопировать кодPYTHON
class IsSuperuserPermission(permissions.BasePermission): def has_permission(self, request, view): return request.user.is_superuser
Чтобы применить ограничения к view-классу, импортируйте IsSuperuserPermission во views.py и добавьте поле permission_classes во view-функцию:
Скопировать кодPYTHON
from .permissions import IsSuperuserPermission class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = (IsSuperuserPermission,)
Встроенный в Django метод .is_superuser вернёт True, если пользователь из request.user — администратор.
Если метод вернёт False, запрос не будет обработан и вернётся такое сообщение:
Скопировать кодJSON
{ "detail": "You do not have permission to perform this action." }
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Новый файл
Новая папка