Давайте крок за кроком створимо API з використанням аутентифікації та кастомних дозволів. Це практичне заняття допоможе нам не лише закріпити вивчені концепції, але й застосувати їх у реальному проєкті.
Мета практичного заняття
- Реалізувати вхід через JWT і управління користувачами.
- Обмежити доступ до маршрутів на основі дозволів.
- Налаштувати кастомні класи дозволів для більш гнучкого контролю доступу.
- Провести тестування аутентифікації та дозволів.
Протягом усього заняття ми будемо додавати функціонал у наш навчальний проєкт, який ви розвивали раніше. Якщо ви раптом "відстали від поїзда", не хвилюйтесь — почнемо з мінімального набору вимог.
Крок 1: підготовка проєкту
Якщо у тебе ще немає проєкту з DRF, виконай наступні кроки, щоб швидко його створити:
Активуй віртуальне середовище:
source venv/bin/activate # Linux/MacOS venv\Scripts\activate # WindowsВстанови Django та DRF:
pip install django djangorestframeworkСтвори новий проєкт:
django-admin startproject myproject cd myprojectСтвори додаток:
python manage.py startapp myappЗареєструй додаток у
settings.py:INSTALLED_APPS = [ # ... 'rest_framework', 'myapp', ]
Тепер у нас є все необхідне для роботи. Погнали далі!
Крок 2: встановлення та налаштування JWT
У попередніх лекціях ми обговорювали JWT та його переваги. Зараз налаштуємо проєкт для роботи з JWT.
Встановіть бібліотеку
djangorestframework-simplejwt:pip install djangorestframework-simplejwtНалаштуйте автентифікацію у проєкті. Додайте наступні параметри у
settings.py:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], }Додайте URL для отримання токенів. У
myproject/urls.pyпідключіть маршрути:from django.urls import path from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns = [ path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ]
Тепер, щоб отримати JWT, потрібно буде зробити POST-запит на /api/token/ з логіном і паролем користувача.
Крок 3: створення захищеного маршруту
Додамо приклад захищеного маршруту, до якого можна звертатися тільки після автентифікації.
У
myapp/views.pyстворіть простий APIView:from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated class ProtectedView(APIView): permission_classes = [IsAuthenticated] def get(self, request): return Response({"message": "Ти авторизований, ласкаво просимо!"})Додайте маршрут для цієї в'юшки у
myapp/urls.py:from django.urls import path from .views import ProtectedView urlpatterns = [ path('protected/', ProtectedView.as_view(), name='protected'), ]Підключіть маршрути додатку до основного файлу
urls.py:from django.urls import include urlpatterns = [ # ... path('api/', include('myapp.urls')), ]
Спробуйте звернутися до /api/protected/ без JWT. Ви повинні отримати відповідь з кодом 401 (Unauthorized). Тепер додайте токен у заголовок запиту, і захист пропустить вас.
Крок 4: створення кастомного дозволу
Тепер давайте ускладнимо завдання. Створимо кастомний дозвіл, який забороняє доступ до маршруту користувачам з email-адресами у домені example.com (привіт спамерам!).
У
myapp/permissions.pyстворіть новий клас:from rest_framework.permissions import BasePermission class IsNotExampleDotComUser(BasePermission): def has_permission(self, request, view): # Перевіряємо email користувача (якщо він авторизований) if request.user and request.user.is_authenticated: return not request.user.email.endswith('@example.com') return FalseОновіть
ProtectedView, щоб використовувати цей дозвіл:from .permissions import IsNotExampleDotComUser class ProtectedView(APIView): permission_classes = [IsNotExampleDotComUser] def get(self, request): return Response({"message": "Ти не спамер, ласкаво просимо!"})
Тепер спробуйте протестувати маршрут /api/protected/ з користувачем, у якого email закінчується на @example.com. Доступ буде заборонено.
Крок 5: тестування
Тестування — це важливо! Перевіримо, як працюють наші маршрути та дозволи.
Встановіть
pytestіpytest-django:pip install pytest pytest-djangoСтворіть файл
tests/test_permissions.pyу додаткуmyapp:import pytest from rest_framework.test import APIClient from django.contrib.auth.models import User @pytest.mark.django_db def test_protected_view_success(): client = APIClient() user = User.objects.create_user(username='testuser', email='user@domain.com', password='testpass') client.force_authenticate(user=user) response = client.get('/api/protected/') assert response.status_code == 200 assert response.data['message'] == "Ти не спамер, ласкаво просимо!" @pytest.mark.django_db def test_protected_view_email_restricted(): client = APIClient() user = User.objects.create_user(username='spamuser', email='spam@example.com', password='testpass') client.force_authenticate(user=user) response = client.get('/api/protected/') assert response.status_code == 403 # ЗабороненоЗапустіть тести:
pytest
Якщо все працює, ви побачите зелені галочки у виводі.
Крок 6: застосування дозволів до інших маршрутів
Тепер ви можете легко додавати інші рівні захисту вашому API. Наприклад, можна використовувати вбудований IsAdminUser, щоб дозволити доступ до певних маршрутів лише адміністраторам, або комбінувати кілька дозволів.
Приклад комбінованого дозволу:
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.decorators import api_view, permission_classes
@api_view(['GET'])
@permission_classes([IsAuthenticated, IsAdminUser])
def admin_only_view(request):
return Response({"message": "Це секретна сторінка для адмінів!"})
Практичне завдання для самостійної роботи
- Реалізуйте новий маршрут, доступний тільки для адміністраторів.
- Створіть кастомний дозвіл, який забороняє доступ користувачам з датою реєстрації старше 30 днів.
- Напишіть тести для всіх доданих маршрутів і дозволів.
Використовуйте надані приклади як основу для свого коду. Але будьте уважні: тести не просто перевіряють ваш додаток, вони ще й ваші "друзі", які допоможуть уникнути регресій у майбутньому.
Тепер ваш API готовий до використання в реальних додатках, і ви можете бути впевнені, що безпека на рівні доступу до даних під контролем. 🚀
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ