Сьогодні ми заглибимось у два дуже популярних класи дозволів: 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": "Вивчити DRF"}, {"id": 2, "task": "Практикувати безпеку"}]
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": "Всі системи працюють", "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 днів",
"active_users": 1024,
}
return Response(stats)
Тепер, якщо спробувати отримати доступ до цього ендпоінту без адміністративних прав, DRF автоматично поверне 403 Forbidden.
{
"detail": "У вас немає дозволу виконувати цю дію."
}
Комбінуємо IsAuthenticated та IsAdminUser
Ти можеш комбінувати декілька класів дозволів, щоб використовувати більш складні політики доступу. Це робиться за допомогою логічного оператора "АБО" (|) або "І" (&).
permission_classes = [IsAuthenticated & IsAdminUser]
Таким чином, ти можеш гнучко керувати доступом до API.
Загальні поради та типові помилки
Працюючи з IsAuthenticated та IsAdminUser, варто пам'ятати наступні моменти:
- Відсутність аутентифікації. Якщо ти забув підключити аутентифікацію (наприклад, токен або сесії), навіть з
IsAuthenticatedтвій API залишиться вразливим. Переконайся, що твій проект налаштований правильно. - Права доступу до адмінки. Не давай користувачам права адміністратора без необхідності. Флаг
is_staff=Trueмає бути строго під контролем. - Кешування відповідей. Якщо ти використовуєш кешування у проекті, не забудь врахувати обмеження. Випадкове кешування адміністративних даних може призвести до витоків.
- Юніт-тести. Завжди тестуй свої ендпоінти на доступність. Це допоможе уникнути ситуацій, коли важливий метод недоступний або, навпаки, доступний для всіх.
Практичне завдання
- Налаштуйте представлення з використанням
IsAuthenticated. Створіть API для управління завданнями, де тільки автентифіковані користувачі можуть бачити свої завдання. - Створіть адміністративний ендпоінт з використанням
IsAdminUser. Додайте вивід системної статистики у форматі JSON (наприклад, завантаженість процесора або загальна статистика користувачів). - Перевірте роботу обох ендпоінтів, а потім спробуйте написати свої тести для перевірки дозволів.
На цьому етапі ваш API вже набуває рис професійного рішення! 🚀
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ