Ответ
JWT (JSON Web Token) — это открытый стандарт (RFC 7519) для создания токенов доступа, которые удостоверяют некоторую информацию (claims) в виде JSON-объекта. Они широко используются для аутентификации и авторизации в веб-приложениях и API.
Преимущества
- Stateless (отсутствие состояния на сервере): Серверу не нужно хранить информацию о сессиях. Вся необходимая информация (ID пользователя, роли, срок действия) содержится в самом токене. Это упрощает горизонтальное масштабирование, так как любой экземпляр сервиса может валидировать токен.
- Самодостаточность и переносимость: JWT можно безопасно передавать между различными сервисами (например, в микросервисной архитектуре), так как он содержит всю необходимую информацию для авторизации.
- Криптографическая защита: Содержимое токена защищено цифровой подписью (например, с использованием алгоритмов
HS256илиRS256), что гарантирует его целостность и невозможность подделки данных (payload) без секретного ключа.
Недостатки
- Невозможность принудительного отзыва: Однажды выпущенный токен действителен до истечения своего срока (
exp). Его нельзя отозвать со стороны сервера стандартными средствами. Решение: использовать короткий срок жизни (5-15 минут) и применять refresh-токены для получения новых access-токенов. - Уязвимость к XSS-атакам: При хранении JWT в
localStorageна клиенте он становится доступен для кражи через XSS-уязвимости. Решение: хранить токен вHttpOnlycookie, что делает его недоступным для JavaScript. - Больший размер: JWT содержит больше данных, чем обычный идентификатор сессии, что незначительно увеличивает размер каждого запроса.
Пример использования с PyJWT в Python
import jwt
import datetime
# Секретный ключ для подписи токена (должен храниться в секрете)
SECRET_KEY = "your-super-secret-key"
# 1. Создание (кодирование) токена
payload = {
'user_id': 123,
'roles': ['user', 'reader'],
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30) # Срок жизни 30 минут
}
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
print(f"Сгенерированный токен: {token}")
# 2. Проверка (декодирование) токена
try:
decoded_payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
print(f"Декодированные данные: {decoded_payload}")
except jwt.ExpiredSignatureError:
print("Ошибка: срок действия токена истек!")
except jwt.InvalidTokenError:
print("Ошибка: невалидный токен!")