🏠 Домашнее задание 18 — Урок 40

← К оглавлению урока

📋 ДЗ из LMS: Python Advanced: Домашнее задание 18

⚡ Суть ДЗ 18

Три задания: (1) настроить JWT-аутентификацию через SimpleJWT, (2) добавить пермишены ко всем представлениям, (3) настроить глобальную пагинацию (5 элементов). Сдать: ссылка на git + скриншоты из Postman.

Текст задания из LMS

Домашнее задание: Реализация аутентификации JWT и пермишенов. Глобальная пагинация.

Цель: Настроить JWT (JSON Web Token) аутентификацию с использованием SimpleJWT и реализовать пермишены для защиты API. Убедитесь, что только авторизованные пользователи могут выполнять определённые действия.

Задание 1: Настройка JWT аутентификации

Шаги для выполнения:

  1. Установите djangorestframework-simplejwt. Убедитесь, что библиотека установлена.
  2. Настройте аутентификацию в settings.py. Добавьте конфигурации SimpleJWT.
  3. Добавьте маршруты для получения и обновления JWT токенов.
  4. Проверьте, что эндпоинты работают.

Задание 2: Реализация пермишенов для API

Шаги для выполнения:

  1. Продумайте пермишены. Определите, какие разрешения должны быть на представлениях.
  2. Примените пермишены к API представлениям. Добавьте пермишены ко всем представлениям.
  3. Проверьте, что пермишены работают согласно их настройкам.

Задание 3: Настройка глобальной пагинации в проекте

  1. Обновить настройки проекта: подключить глобальную пагинацию в настройках Django REST framework, выбрав класс пагинации из тех, что рассматривались на занятиях.
  2. Протестировать эндпоинты: установить для пагинации возврат 5 элементов по умолчанию.
  3. Проверить работу эндпоинтов с добавлением пагинации.

Оформление ответа

  • Прикрепите ссылку на git.
  • Приложите скриншоты из Postman, подтверждающие: успешное использование JWT токенов, соблюдение пермишенов при работе с задачами, пагинацию страниц при HTTP GET ответах.

Подготовка окружения

1. Создание и активация виртуального окружения

# Windows PowerShell
python -m venv venv
.\venv\Scripts\activate

# Проверка
python --version
pip --version

2. Установка зависимостей

pip install django djangorestframework djangorestframework-simplejwt
pip freeze > requirements.txt

3. Git-инициализация

git init
echo "venv/" > .gitignore
echo "__pycache__/" >> .gitignore
echo "*.pyc" >> .gitignore
echo "db.sqlite3" >> .gitignore
git add .
git commit -m "Initial project setup"

Пошаговое решение

Предполагается, что у вас уже есть Django-проект с DRF (например, проект с Tasks и SubTasks из предыдущих ДЗ).

Шаг 1: Установка Simple JWT

pip install djangorestframework-simplejwt

Шаг 2: Обновление settings.py

# myproject/settings.py
from datetime import timedelta

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    # rest_framework.authtoken НЕ нужен для JWT
    'tasks',  # ваше приложение
]

# ======= JWT-аутентификация =======
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    # Задание 2: глобальные пермишены
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    # Задание 3: глобальная пагинация
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5,  # 5 элементов по умолчанию
}

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'ALGORITHM': 'HS256',
    'AUTH_HEADER_TYPES': ('Bearer',),
}

Связь с теорией: теория JWT объясняет параметры ACCESS_TOKEN_LIFETIME и REFRESH_TOKEN_LIFETIME.

Шаг 3: Обновление urls.py

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('admin/', admin.site.urls),
    # JWT endpoints
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    # Ваши API endpoints
    path('api/', include('tasks.urls')),
]

Шаг 4: Применение пермишенов (Задание 2)

Глобальные настройки из шага 2 автоматически применяются ко всем представлениям. Для явного контроля можно переопределить в конкретных view:

# tasks/views.py
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
from .models import Task, SubTask
from .serializers import TaskSerializer, SubTaskSerializer

class TaskListCreateView(ListCreateAPIView):
    serializer_class = TaskSerializer
    # Наследует IsAuthenticated из DEFAULT_PERMISSION_CLASSES
    # Явно указывать не обязательно, но рекомендуется для документирования намерения:
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        # Пользователь видит только свои задачи
        return Task.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        # Автоматически привязать задачу к текущему пользователю
        serializer.save(user=self.request.user)


class TaskDetailView(RetrieveUpdateDestroyAPIView):
    serializer_class = TaskSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return Task.objects.filter(user=self.request.user)

Связь с теорией: классы разрешений объясняют IsAuthenticated и IsAuthenticatedOrReadOnly.

Шаг 5: Применение миграций

python manage.py migrate
python manage.py createsuperuser
# Создайте тестового пользователя: имя, email, пароль

Шаг 6: Проверка в Postman

6.1. Получение JWT-токенов

  1. POST http://127.0.0.1:8000/api/token/
  2. Body → raw → JSON:
{
    "username": "admin",
    "password": "your_password"
}

Ответ должен содержать:

{
    "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Сохраните оба токена. Сделайте скриншот — это доказательство для ДЗ.

6.2. Доступ без токена (проверка пермишенов)

  1. GET http://127.0.0.1:8000/api/tasks/ без заголовка Authorization
  2. Ожидаемый ответ: HTTP 401 Unauthorized
{"detail": "Authentication credentials were not provided."}

Сделайте скриншот — демонстрирует работу пермишенов.

6.3. Доступ с токеном

  1. GET http://127.0.0.1:8000/api/tasks/
  2. Headers: Authorization: Bearer eyJhbGciOiJIUzI1NiIs... (access-токен)
  3. Ожидаемый ответ: список задач с пагинацией
{
    "count": 12,
    "next": "http://127.0.0.1:8000/api/tasks/?page=2",
    "previous": null,
    "results": [
        {"id": 1, "title": "Task 1", ...},
        ...  // 5 элементов
    ]
}

Сделайте скриншот — демонстрирует JWT + пагинацию.

6.4. Обновление access-токена

  1. POST http://127.0.0.1:8000/api/token/refresh/
  2. Body → raw → JSON:
{"refresh": "eyJhbGci... (refresh-токен)"}

Ответ: новый access-токен.

Проверка в VS Code

Запуск сервера (терминал)

# В терминале VS Code (Ctrl+`)
.\venv\Scripts\activate
python manage.py runserver

Отладка (F5 и launch.json)

Создайте файл .vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Django Server",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/manage.py",
            "args": ["runserver", "--noreload"],
            "django": true,
            "justMyCode": true
        }
    ]
}

Точки останова для отладки JWT

  1. Откройте tasks/views.py
  2. Поставьте точку останова на строке def get_queryset(self): (кликните слева от номера строки)
  3. Нажмите F5 (или Run → Start Debugging)
  4. В Postman отправьте GET-запрос с токеном
  5. VS Code остановится на точке — изучите request.user в панели Variables

Что проверить в отладчике

  • request.user — должен быть объект User (не AnonymousUser)
  • request.user.username — имя вошедшего пользователя
  • request.auth — JWT-токен (объект ValidatedToken)
  • self.get_queryset() — queryset отфильтрован по пользователю

Связь с разделами урока

ЗаданиеТеорияПримеры
Задание 1: JWT Часть 4: JWT-аутентификация Пример 3: JWT
Задание 2: пермишены Часть 5: Разрешения Пример 4: смешанные разрешения
Задание 3: пагинация ⚠️ Проверить по документации — пагинация урока 38 Справочник — settings.py
Чек-лист перед сдачей:
  • JWT установлен и настроен в settings.py
  • Эндпоинты /api/token/ и /api/token/refresh/ работают
  • Запрос без токена возвращает 401
  • Запрос с корректным Bearer-токеном возвращает данные
  • Пагинация возвращает 5 элементов + поля count, next, previous
  • Скриншоты из Postman готовы (токен, 401, список с пагинацией)
  • Код запушен в git