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) у проєкті змінився.
- Рішення: переконайтеся, що токен не був підроблений.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ