JavaRush /Курси /Модуль 3: Django /Практичне заняття з налаштування аутентифікації та дозвол...

Практичне заняття з налаштування аутентифікації та дозволів

Модуль 3: Django
Рівень 18 , Лекція 9
Відкрита

Давайте крок за кроком створимо API з використанням аутентифікації та кастомних дозволів. Це практичне заняття допоможе нам не лише закріпити вивчені концепції, але й застосувати їх у реальному проєкті.

Мета практичного заняття

  1. Реалізувати вхід через JWT і управління користувачами.
  2. Обмежити доступ до маршрутів на основі дозволів.
  3. Налаштувати кастомні класи дозволів для більш гнучкого контролю доступу.
  4. Провести тестування аутентифікації та дозволів.

Протягом усього заняття ми будемо додавати функціонал у наш навчальний проєкт, який ви розвивали раніше. Якщо ви раптом "відстали від поїзда", не хвилюйтесь — почнемо з мінімального набору вимог.

Крок 1: підготовка проєкту

Якщо у тебе ще немає проєкту з DRF, виконай наступні кроки, щоб швидко його створити:

  1. Активуй віртуальне середовище:

    source venv/bin/activate  # Linux/MacOS
    venv\Scripts\activate     # Windows
    
  2. Встанови Django та DRF:

    pip install django djangorestframework
    
  3. Створи новий проєкт:

    django-admin startproject myproject
    cd myproject
    
  4. Створи додаток:

    python manage.py startapp myapp
    
  5. Зареєструй додаток у settings.py:

    INSTALLED_APPS = [
        # ...
        'rest_framework',
        'myapp',
    ]
    

Тепер у нас є все необхідне для роботи. Погнали далі!

Крок 2: встановлення та налаштування JWT

У попередніх лекціях ми обговорювали JWT та його переваги. Зараз налаштуємо проєкт для роботи з JWT.

  1. Встановіть бібліотеку djangorestframework-simplejwt:

    pip install djangorestframework-simplejwt
    
  2. Налаштуйте автентифікацію у проєкті. Додайте наступні параметри у settings.py:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ],
    }
    
  3. Додайте 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: створення захищеного маршруту

Додамо приклад захищеного маршруту, до якого можна звертатися тільки після автентифікації.

  1. У 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": "Ти авторизований, ласкаво просимо!"})
  2. Додайте маршрут для цієї в'юшки у myapp/urls.py:

    from django.urls import path
    from .views import ProtectedView
    
    urlpatterns = [
        path('protected/', ProtectedView.as_view(), name='protected'),
    ]
  3. Підключіть маршрути додатку до основного файлу urls.py:

    from django.urls import include
    
    urlpatterns = [
        # ...
        path('api/', include('myapp.urls')),
    ]

Спробуйте звернутися до /api/protected/ без JWT. Ви повинні отримати відповідь з кодом 401 (Unauthorized). Тепер додайте токен у заголовок запиту, і захист пропустить вас.

Крок 4: створення кастомного дозволу

Тепер давайте ускладнимо завдання. Створимо кастомний дозвіл, який забороняє доступ до маршруту користувачам з email-адресами у домені example.com (привіт спамерам!).

  1. У 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
  2. Оновіть ProtectedView, щоб використовувати цей дозвіл:

    from .permissions import IsNotExampleDotComUser
    
    class ProtectedView(APIView):
        permission_classes = [IsNotExampleDotComUser]
    
        def get(self, request):
            return Response({"message": "Ти не спамер, ласкаво просимо!"})

Тепер спробуйте протестувати маршрут /api/protected/ з користувачем, у якого email закінчується на @example.com. Доступ буде заборонено.

Крок 5: тестування

Тестування — це важливо! Перевіримо, як працюють наші маршрути та дозволи.

  1. Встановіть pytest і pytest-django:

    pip install pytest pytest-django
    
  2. Створіть файл 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  # Заборонено
  3. Запустіть тести:

    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": "Це секретна сторінка для адмінів!"})

Практичне завдання для самостійної роботи

  1. Реалізуйте новий маршрут, доступний тільки для адміністраторів.
  2. Створіть кастомний дозвіл, який забороняє доступ користувачам з датою реєстрації старше 30 днів.
  3. Напишіть тести для всіх доданих маршрутів і дозволів.

Використовуйте надані приклади як основу для свого коду. Але будьте уважні: тести не просто перевіряють ваш додаток, вони ще й ваші "друзі", які допоможуть уникнути регресій у майбутньому.

Тепер ваш API готовий до використання в реальних додатках, і ви можете бути впевнені, що безпека на рівні доступу до даних під контролем. 🚀

3
Опитування
JWT (JSON Web Tokens), рівень 18, лекція 9
Недоступний
JWT (JSON Web Tokens)
JWT (JSON Web Tokens)
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ