🏠 Домашнее задание 18 — Урок 40
⚡ Суть ДЗ 18
Три задания: (1) настроить JWT-аутентификацию через SimpleJWT, (2) добавить пермишены ко всем представлениям, (3) настроить глобальную пагинацию (5 элементов). Сдать: ссылка на git + скриншоты из Postman.
Текст задания из LMS
Цель: Настроить JWT (JSON Web Token) аутентификацию с использованием SimpleJWT и реализовать пермишены для защиты API. Убедитесь, что только авторизованные пользователи могут выполнять определённые действия.
Задание 1: Настройка JWT аутентификации
Шаги для выполнения:
- Установите
djangorestframework-simplejwt. Убедитесь, что библиотека установлена. - Настройте аутентификацию в
settings.py. Добавьте конфигурации SimpleJWT. - Добавьте маршруты для получения и обновления JWT токенов.
- Проверьте, что эндпоинты работают.
Задание 2: Реализация пермишенов для API
Шаги для выполнения:
- Продумайте пермишены. Определите, какие разрешения должны быть на представлениях.
- Примените пермишены к API представлениям. Добавьте пермишены ко всем представлениям.
- Проверьте, что пермишены работают согласно их настройкам.
Задание 3: Настройка глобальной пагинации в проекте
- Обновить настройки проекта: подключить глобальную пагинацию в настройках Django REST framework, выбрав класс пагинации из тех, что рассматривались на занятиях.
- Протестировать эндпоинты: установить для пагинации возврат 5 элементов по умолчанию.
- Проверить работу эндпоинтов с добавлением пагинации.
Оформление ответа
- Прикрепите ссылку на 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-токенов
- POST
http://127.0.0.1:8000/api/token/ - Body → raw → JSON:
{
"username": "admin",
"password": "your_password"
}
Ответ должен содержать:
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Сохраните оба токена. Сделайте скриншот — это доказательство для ДЗ.
6.2. Доступ без токена (проверка пермишенов)
- GET
http://127.0.0.1:8000/api/tasks/без заголовка Authorization - Ожидаемый ответ:
HTTP 401 Unauthorized
{"detail": "Authentication credentials were not provided."}
Сделайте скриншот — демонстрирует работу пермишенов.
6.3. Доступ с токеном
- GET
http://127.0.0.1:8000/api/tasks/ - Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...(access-токен) - Ожидаемый ответ: список задач с пагинацией
{
"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-токена
- POST
http://127.0.0.1:8000/api/token/refresh/ - 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
- Откройте
tasks/views.py - Поставьте точку останова на строке
def get_queryset(self):(кликните слева от номера строки) - Нажмите F5 (или Run → Start Debugging)
- В Postman отправьте GET-запрос с токеном
- 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