Ответ
Ключевое различие заключается в подходе к хранению состояния: обычные токены являются stateful (требуют состояния на сервере), а JWT — stateless (самодостаточны).
Обычный токен (Stateful)
- Что это: Произвольная, уникальная строка (например,
f9a4d4f0-4b7e-4b4e-9b0a-3e5d5f3e5d5f
), которая не несет в себе никакой информации. - Как работает: Сервер генерирует токен, сохраняет его в базе данных или кэше вместе с данными сессии (ID пользователя, права доступа) и отправляет клиенту. При каждом запросе сервер ищет токен в своей базе, чтобы проверить его валидность и получить данные о пользователе.
- Недостаток: Требует обращения к хранилищу при каждом запросе, что создает нагрузку и усложняет горизонтальное масштабирование.
JWT (JSON Web Token, Stateless)
- Что это: Стандартизированный токен (RFC 7519), состоящий из трех частей, закодированных в Base64 и разделенных точками:
Header.Payload.Signature
. - Как работает:
- Header: Метаданные (тип токена, алгоритм подписи).
- Payload: Полезная нагрузка (claims) — данные о пользователе (ID, роли и т.д.).
- Signature: Цифровая подпись, созданная с использованием секрета, известного только серверу. Она гарантирует, что
Header
иPayload
не были изменены.
- Преимущество: Серверу не нужно обращаться к базе данных для проверки токена. Он может валидировать подпись, используя свой секретный ключ, и доверять данным из
Payload
.
Сравнительная таблица:
Характеристика | Обычный токен | JWT |
---|---|---|
Хранение данных | На сервере (БД, кэш) | Внутри токена (Payload ) |
Проверка | Запрос к хранилищу | Криптографическая (проверка подписи) |
Масштабируемость | Сложнее (требует общего хранилища) | Проще (не требует состояния) |
Размер | Короткий | Длиннее из-за данных |
Пример на Python с pyjwt
:
import jwt
# 1. Создание JWT
secret_key = "your-super-secret-key"
payload_data = {"user_id": 123, "role": "admin"}
token = jwt.encode(payload=payload_data, key=secret_key, algorithm="HS256")
print(f"Сгенерированный JWT: {token}")
# 2. Проверка и декодирование JWT (происходит на сервере при запросе)
try:
decoded_payload = jwt.decode(jwt=token, key=secret_key, algorithms=["HS256"])
print(f"Декодированные данные: {decoded_payload}")
except jwt.InvalidTokenError:
print("Невалидный токен!")