Сегодня мы углубимся в два очень популярных класса разрешений: IsAuthenticated и IsAdminUser. Мы разберём их предназначение, сценарии их использования и посмотрим, как они помогают защитить наше приложение. Также будет много примеров, чтобы всё закрепить на практике.
Зачем нужны IsAuthenticated и IsAdminUser
Аутентификация и ограничение доступа — это краеугольные камни безопасности API. Представьте себя охранником, стоящим у входной двери офиса. Кого-то вы пускаете, основываясь на бейдже "Сотрудник компании" (IsAuthenticated), а кого-то только если он администратор здания или директор (IsAdminUser).
IsAuthenticated обеспечивает доступ только для пользователей, которые успешно прошли авторизацию (вошли в систему). Это помогает защитить ресурсы от случайного (или намеренного) доступа со стороны анонимных пользователей.
IsAdminUser, напротив, используется для ограничения доступа только для пользователей с административными правами. Это может быть полезно, например, для управления доступом к чувствительным данным.
IsAuthenticated: доступ только для аутентифицированных пользователей
Как следует из названия, IsAuthenticated предназначен для проверки, что пользователь был аутентифицирован (вход выполнен). Здесь нет сложных условий — если пользователь вошел в систему, то он может получить доступ. Если нет, то его ждёт вежливый HTTP 401 Unauthorized.
Давайте приведём пример. Начнём с базовой настройки. Представим, что у нас есть API для получения списка задач, доступный только авторизованным пользователям. Наша модель Task уже создана и зарегистрирована в проекте.
# views.py
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
class TaskListView(APIView):
permission_classes = [IsAuthenticated] # Ограничиваем доступ только для аутентифицированных пользователей
def get(self, request):
# Получаем задачи текущего пользователя
tasks = [{"id": 1, "task": "Learn DRF"}, {"id": 2, "task": "Write code"}]
return Response(tasks)
Теперь попробуем проверить это в работе.
Если пользователь не аутентифицирован (например, не передал токен или cookie сессии), то он получит:
{ "detail": "Authentication credentials were not provided." }Код ответа:
401 Unauthorized. DRF автоматически обрабатывает такие случаи, чтобы не выдумывать велосипеды.Если пользователь аутентифицирован, то ему вернётся JSON с задачами.
Пример: внедрение IsAuthenticated в маршруты
permission_classes можно комбинировать с маршрутизацией. Вот пример, как это сделать с использованием классов ViewSet:
# views.py
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
class TaskViewSet(ViewSet):
permission_classes = [IsAuthenticated]
def list(self, request):
tasks = [{"id": 1, "task": "Learn DRF"}, {"id": 2, "task": "Practice security"}]
return Response(tasks)
# urls.py
from django.urls import path
from .views import TaskViewSet
urlpatterns = [
path('tasks/', TaskViewSet.as_view({'get': 'list'})),
]
Этот подход работает особенно хорошо в больших приложениях, где требуется унифицированная маршрутизация.
IsAdminUser: доступ только для администраторов
Второе разрешение, IsAdminUser, определяет доступ исключительно для пользователей с административными правами. Но кто считается администратором? В Django пользователь считается администратором, если у него флаг is_staff=True. Именно этот флаг проверяет класс разрешения IsAdminUser.
Приведём ример использования IsAdminUser.
Предположим, у нас есть API для управления конфиденциальными данными, доступный только администраторам.
# views.py
from rest_framework.permissions import IsAdminUser
from rest_framework.views import APIView
from rest_framework.response import Response
class AdminDataView(APIView):
permission_classes = [IsAdminUser] # Только для администраторов
def get(self, request):
# Секретные данные для администраторов
secret_data = {"server_status": "All systems operational", "user_count": 5234}
return Response(secret_data)
Пример: настройка административных эндпоинтов
В реальных проектах администраторы могут получать доступ к информации, недоступной обычным пользователям, например, логам или статистике.
# views.py
from rest_framework.permissions import IsAdminUser
from rest_framework.views import APIView
from rest_framework.response import Response
class ServerStatsView(APIView):
permission_classes = [IsAdminUser]
def get(self, request):
stats = {
"cpu_usage": "35%",
"server_uptime": "100 days",
"active_users": 1024,
}
return Response(stats)
Теперь, если попытаться получить доступ к этому эндпоинту без административных прав, DRF автоматически вернёт 403 Forbidden.
{
"detail": "You do not have permission to perform this action."
}
Комбинируем IsAuthenticated и IsAdminUser
Вы можете комбинировать несколько классов разрешений, чтобы использовать более сложные политики доступа. Это делается с помощью логического оператора "ИЛИ" (|) или "И" (&).
permission_classes = [IsAuthenticated & IsAdminUser]
Таким образом, вы можете гибко управлять доступом к API.
Общие советы и типичные ошибки
Работая с IsAuthenticated и IsAdminUser, стоит помнить следующие моменты:
- Отсутствие аутентификации. Если вы забыли подключить аутентификацию (например, токен или сессии), даже с
IsAuthenticatedваш API останется уязвимым. Убедитесь, что ваш проект настроен корректно. - Права доступа к админке. Не давайте пользователям права администратора без необходимости. Флаг
is_staff=Trueдолжен быть строго под контролем. - Кэширование ответов. Если вы используете кэширование в проекте, не забудьте учесть ограничения. Случайное кэширование администраторских данных может привести к утечкам.
- Юнит-тесты. Всегда тестируйте свои эндпоинты на доступность. Это поможет избежать ситуаций, когда важный метод недоступен или, наоборот, доступен для всех.
Практическое задание
- Настройте представление с использованием
IsAuthenticated. Создайте API для управления задачами, где только аутентифицированные пользователи могут видеть свои задачи. - Создайте административный эндпоинт с использованием
IsAdminUser. Добавьте вывод системной статистики в JSON формате (например, загруженность процессора или общая статистика пользователей). - Проверьте работу обоих эндпоинтов, а затем попробуйте написать свои тесты для проверки разрешений.
На этом этапе ваш API уже приобретает черты профессионального решения! 🚀
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ