Files
public-gists/django-jwt.md
2026-05-23 17:32:27 +03:00

286 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Конечно! Ниже приведён перевод предыдущего ответа на русский язык.
---
### ✅ Как реализовать 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 и т.д.)