JWT и токены
JWT — подписанный токен из трёх частей в base64url, который переносит утверждения о пользователе и проверяется без обращения к базе.
Что такое JWT и токены
JWT расшифровывается как JSON Web Token (произносится «джот», стандарт RFC 7519) — компактный формат токена, который переносит claims (утверждения) о пользователе и подписан выдавшей стороной.
Токен в широком смысле — строка, подтверждающая право на доступ. Токены бывают двух видов, и разница между ними определяет всю архитектуру:
| Opaque-токен | JWT | |
|---|---|---|
| Что внутри | Случайная строка | Данные о пользователе |
| Как проверяется | Запрос в БД или к IdP | Проверка подписи локально |
| Отзыв | Мгновенный: удалить строку | Сложный: живёт до exp |
| Нагрузка | Запрос на каждую проверку | Ноль запросов |
| Когда выбирать | Нужен контроль сессий | Нужна масштабируемость |
Главное свойство JWT — самодостаточность. Сервису не нужно никуда ходить: он проверяет подпись публичным ключом и доверяет содержимому. Это идеально для микросервисов и горизонтального масштабирования — любая реплика за балансировщиком проверит токен сама, без общего хранилища сессий.
Структура и расшифровка JWT
Три части, разделённые точками: header.payload.signature.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSXZhbiJ9.dBjftJeZ4CVP...
└────────── header ──────────┘ └───────── payload ─────────┘ └─ signature ─┘
Расшифровка JWT — это не расшифровка. Здесь кроется самое опасное заблуждение: JWT по умолчанию не зашифрован, он лишь закодирован в base64url и подписан. Прочитать содержимое может кто угодно, без всяких ключей:
echo 'eyJzdWIiOiIxMjMiLCJuYW1lIjoiSXZhbiJ9' | base64 -d
# {"sub":"123","name":"Ivan"}
# или целиком, вторая часть токена:
echo "$JWT" | cut -d. -f2 | base64 -d 2>/dev/null | jq
Подпись защищает от подделки, а не от чтения. Поэтому: никогда не кладите в payload пароли, ключи, персональные данные или что-либо, что не должно попасть на глаза владельцу токена и любому, кто перехватит его из логов.
Стандартные claims: iss (кто выдал), sub (о ком), aud (для кого), exp (до какого времени), nbf (не раньше), iat (когда выдан), jti (уникальный id токена).
Алгоритмы подписи
- HS256 — симметричный HMAC. Один секрет и подписывает, и проверяет. Годится, когда выдаёт и проверяет один сервис.
- RS256 / ES256 — асимметричные. Приватным ключом подписывает IdP, публичным проверяют все остальные. Единственный правильный выбор для SSO и микросервисов: утечка публичного ключа безобидна.
Классические уязвимости, о которых стоит знать:
alg: none. Атакующий подменяет алгоритм на «без подписи» и правит payload. Библиотека, доверяющая полюalgиз самого токена, впустит его. Всегда задавайте ожидаемый алгоритм при проверке явно.- Путаница HS256/RS256. Токен, подписанный публичным RSA-ключом как HMAC-секретом. Лечится тем же — жёстким указанием алгоритма.
- Отсутствие проверки
expиaud. Токен для другого сервиса или просроченный не должен приниматься.
Access и refresh
Проблема JWT — отзыв. Уволили сотрудника, а его токен действует до exp. Стандартное решение:
- Access-токен — JWT, живёт минуты (5–15). Ходит в каждый запрос в заголовке
Authorization: Bearer <token>. Отзывать не нужно — сам протухнет. - Refresh-токен — opaque, живёт дни или недели, хранится в БД. Меняется на новый access. Отзывается мгновенно — удалением записи.
Так вы получаете и масштабируемость JWT, и контроль над сессиями. Для критичных операций дополнительно ведут denylist по jti — но если он нужен постоянно, значит JWT здесь просто не подходил.
API-токены
API-токен (он же API-ключ) — долгоживущий токен для машины, а не для человека: скрипт, интеграция, CI/CD. Чаще opaque, чем JWT. Правила обращения жёстче, потому что срок жизни длинный: минимальные права по RBAC, отдельный токен на каждую интеграцию (чтобы отзыв не ломал всё разом), хранение в Vault или секретах CI, а не в репозитории, плановая ротация.
Токен в заголовке передаётся открытым текстом — работать он обязан только поверх TLS.
Связанные термины
- OAuth — протокол, который выдаёт токены
- SSO — где JWT используется как результат входа
- IAM / IdP — кто подписывает токены
- API-ключи — токены для машинных интеграций
- Аутентификация — процесс, результатом которого становится токен
Готовы запустить GPU-задачу?
Запустить GPU-сервер