commit 05464ee5f2773c38ca563683f3dc79c9b1429668 Author: blankhex Date: Sat May 23 17:32:27 2026 +0300 Initial commit diff --git a/django-jwt.md b/django-jwt.md new file mode 100644 index 0000000..6a38f16 --- /dev/null +++ b/django-jwt.md @@ -0,0 +1,286 @@ +Конечно! Ниже приведён перевод предыдущего ответа на русский язык. + +--- + +### ✅ Как реализовать JWT в проекте Django с помощью `djangorestframework-simplejwt` (без `python-jose`) + +Чтобы реализовать **JWT (JSON Web Tokens)** в проекте Django с использованием пакета **`djangorestframework-simplejwt`** (без `python-jose`), следуйте пошаговой инструкции ниже. Этот пакет лёгкий, хорошо поддерживается и отлично интегрируется с Django REST Framework. + +--- + +### 📌 Предварительные требования + +Убедитесь, что у вас установлено: +- Django +- Django REST Framework (`djangorestframework`) +- Python 3.6 или выше + +--- + +### 1. Установите необходимые пакеты + +```bash +pip install djangorestframework +pip install djangorestframework-simplejwt +``` + +> ✅ Примечание: `simplejwt` **не требует** `python-jose` или `cryptography` для базового алгоритма HMAC (HS256). Он использует встроенный механизм подписи Django или стандартные модули Python `hmac` и `hashlib`. Модуль `cryptography` нужен только при использовании RSA (RS256). + +--- + +### 2. Обновите `settings.py` + +Добавьте `rest_framework` и настройте `SimpleJWT`: + +```python +# settings.py + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + # Сторонние приложения + 'rest_framework', + + # Ваши приложения + 'myapp', +] + +# Настройки REST Framework +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ), +} + +# Настройки SimpleJWT (необязательно) +from datetime import timedelta + +SIMPLE_JWT = { + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), + 'ROTATE_REFRESH_TOKENS': False, + 'BLACKLIST_AFTER_ROTATION': True, + 'UPDATE_LAST_LOGIN': False, + + 'ALGORITHM': 'HS256', + 'SIGNING_KEY': SECRET_KEY, # Использует SECRET_KEY из Django + 'VERIFYING_KEY': None, + 'AUDIENCE': None, + 'ISSUER': None, + 'JSON_ENCODER': None, + 'JWK_URL': None, + 'LEEWAY': 0, + + 'AUTH_HEADER_TYPES': ('Bearer',), + 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', + 'USER_ID_FIELD': 'id', + 'USER_ID_CLAIM': 'user_id', + 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', + + 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), + 'TOKEN_TYPE_CLAIM': 'token_type', + 'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser', + + 'JTI_CLAIM': 'jti', +} +``` + +> 🔐 `SIGNING_KEY` по умолчанию берётся из `SECRET_KEY`, если не указан явно. HS256 использует симметричное шифрование — один и тот же ключ для подписи и проверки. + +--- + +### 3. Настройте URL-адреса + +Добавьте в основной `urls.py` эндпоинты для получения и обновления токенов: + +```python +# 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), + path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), + path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path('api/', include('myapp.urls')), +] +``` + +--- + +### 4. Защитите свои API-эндпоинты + +Используйте декораторы или классы для защиты представлений. + +Пример с функцией: + +```python +# views.py в вашем приложении +from rest_framework.decorators import api_view, permission_classes, authentication_classes +from rest_framework.response import Response +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import SessionAuthentication + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([SessionAuthentication]) # Опционально: отключите сессию, если используете только JWT +def protected_view(request): + return Response({ + 'message': 'Привет! Вы прошли аутентификацию!', + 'user': request.user.username + }) +``` + +Или с классом: + +```python +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': f'Привет, {request.user.username}, вы авторизованы через JWT!' + }) +``` + +Добавьте маршрут в `myapp/urls.py`: + +```python +# myapp/urls.py +from django.urls import path +from .views import ProtectedView + +urlpatterns = [ + path('protected/', ProtectedView.as_view(), name='protected'), +] +``` + +--- + +### 5. Проверка работы JWT + +#### Шаг 1: Получение токенов + +Отправьте POST-запрос на `/api/token/` с данными пользователя: + +```json +POST /api/token/ +Content-Type: application/json + +{ + "username": "ваш_логин", + "password": "ваш_пароль" +} +``` + +✅ Ответ: +```json +{ + "refresh": "eyJ...", + "access": "eyJ..." +} +``` + +#### Шаг 2: Доступ к защищённому эндпоинту + +Используйте токен доступа в заголовке: + +```http +GET /api/protected/ +Authorization: Bearer eyJ... +``` + +#### Шаг 3: Обновление токена доступа + +Когда токен доступа истекает: + +```json +POST /api/token/refresh/ +Content-Type: application/json + +{ + "refresh": "eyJ..." +} +``` + +✅ Вернётся новый `access` токен. + +--- + +### 6. Дополнительно: Добавление пользовательских данных в токен + +Вы можете добавить свои поля в токен, переопределив `TokenObtainPairSerializer`. + +```python +# serializers.py +from rest_framework_simplejwt.serializers import TokenObtainPairSerializer +from rest_framework_simplejwt.views import TokenObtainPairView + +class MyTokenObtainPairSerializer(TokenObtainPairSerializer): + @classmethod + def get_token(cls, user): + token = super().get_token(user) + + # Добавляем свои поля + token['username'] = user.username + token['email'] = user.email + token['is_staff'] = user.is_staff + + return token + +# views.py +class MyTokenObtainPairView(TokenObtainPairView): + serializer_class = MyTokenObtainPairSerializer +``` + +Обновите URL: + +```python +# urls.py +path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'), +``` + +Теперь в токене будут дополнительные данные! + +--- + +### ✅ Итог + +Вы успешно реализовали JWT в Django с помощью `djangorestframework-simplejwt` без использования `python-jose`. Основные моменты: + +- Используется встроенная криптография Django (`hmac` + `sha256`) для HS256 +- Не нужны `python-jose`, `cryptography` и другие внешние зависимости +- Простая интеграция с DRF +- Поддержка access/refresh токенов «из коробки» +- Возможность настройки содержимого токена + +--- + +### 🛡️ Рекомендации по безопасности + +- Храните `SECRET_KEY` в безопасности и никогда не показывайте его. +- Используйте HTTPS в продакшене. +- Включите чёрный список токенов, если пользователи могут выходить из системы. +- Установите разумное время жизни токенов. + +--- + +Сообщите, если хотите: +- Реализовать регистрацию пользователей +- Настроить чёрный список токенов +- Использовать RS256 (асимметричное шифрование) +- Добавить выход из системы (с блокировкой токена) +- Интеграцию с фронтендом (React, Vue и т.д.) \ No newline at end of file