JSON Web Token (JWT) — это стандарт (RFC 7519) для создания токенов, которые могут быть использованы для передачи данных между двумя сторонами. JWT токены построены на JSON и содержат три ключевых части:
- Header (Заголовок): содержит информацию о типе токена и алгоритме шифрования.
- Payload (Полезная нагрузка): содержит пользовательские данные, например, идентификатор пользователя или его роли.
- Signature (Подпись): служит для проверки подлинности токена.
Итак, почему все любят JWT?
- Самодостаточность: JWT содержит всю необходимую информацию, чтобы сервер мог проверить его подлинность и решить, предоставить ли доступ.
- Масштабируемость: Никакого сохранения токенов на сервере. Все данные хранятся в самом токене.
- Безопасность: JWT подписаны (и могут быть зашифрованы), что делает их безопасными для передачи данных.
Пример структуры JWT выглядит так:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Что ж, если вы ещё не почувствовали себя шпионом из фильма, то дальше точно почувствуете.
Преимущества использования JWT в проектах
- Отсутствие необходимости хранить токены на сервере. Это снижает нагрузку на сервер и упрощает масштабирование приложений (например, в микро-сервисах).
- Поддержка различных платформ. JWT работает на любых устройствах (мобильных, серверных, фронтенд) без проблем.
- Высокая безопасность. Данные в JWT подписаны, что защищает от подделки токенов.
Теперь, поговорив о преимуществах, давайте воплотим их в жизнь, интегрировав JWT в наш проект.
Установка необходимых библиотек
Мы будем использовать библиотеку djangorestframework-simplejwt, популярное решение для работы с JWT в DRF.
Установим библиотеку с помощью pip:
pip install djangorestframework-simplejwt
Вот это было легко! Даже легче, чем настроить будильник.
Настройка проекта для работы с JWT
Шаг 1: изменение настроек аутентификации
Откройте файл settings.py вашего проекта и добавьте SimpleJWT в список REST framework authentication classes:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
Здесь мы указываем, что теперь аутентификация через JWT будет применяться в нашем проекте.
Шаг 2: настройка токенов в URLConf
Теперь нужно создать эндпоинты для получения и обновления JWT. Откройте файл 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'), # Для обновления токена
]
Здесь:
TokenObtainPairViewотвечает за выдачу пары токенов: доступа (access token) и обновления (refresh token).TokenRefreshViewпозволяет получить новый токен доступа, используя токен обновления.
Шаг 3: тестирование эндпоинтов
Запустите сервер разработки:
python manage.py runserver
Теперь вы можете протестировать эндпоинты с помощью Postman или cURL.
- Получение токена
Отправьте POST-запрос на эндпоинт /api/token/ с учётными данными пользователя:
{
"username": "admin",
"password": "admin_password"
}
Если всё настроено правильно, вы получите ответ типа:
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
- Использование токена
Теперь добавьте полученный access токен в заголовок авторизации для каждого последующего запроса:
Authorization: Bearer <access_token>
- Обновление токена
Когда токен доступа истечёт, вы можете отправить POST-запрос на /api/token/refresh/ с refresh токеном:
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
В результате вам вернётся новый access токен.
Дополнительные настройки JWT
Настройка времени жизни токенов
По умолчанию токены доступа и обновления имеют определённое время жизни. Настроить их можно в settings.py:
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': True, # Новый refresh токен при каждой выдаче
'BLACKLIST_AFTER_ROTATION': True, # Запрет использования старых refresh токенов
}
Таким образом, вы можете настроить время жизни токенов, подходящее для вашего проекта.
Добавление пользовательских данных в токен
Вы хотите, чтобы в токене была информация о пользователе? Легко! Создайте собственный сериализатор для генерации токенов. В вашем приложении создайте файл serializers.py и добавьте туда следующий код:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# Добавляем пользовательские данные
token['email'] = user.email
token['is_superuser'] = user.is_superuser
return token
Теперь вы можете указать этот сериализатор в маршруте:
from django.urls import path
from .serializers import CustomTokenObtainPairSerializer
urlpatterns = [
path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
]
Типичные ошибки и их решение
Ошибка: "JWT token is invalid"
- Причина: токен истёк или был неправильно сгенерирован.
- Решение: Проверьте время жизни токенов и используйте refresh токен для генерации нового.
Ошибка: "Token signature is invalid"
- Причина: возможно, кто-то изменил токен или тайный ключ (SECRET_KEY) в проекте изменился.
- Решение: убедитесь, что токен не был подделан.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ