Что такое JWT? Полное руководство по JSON Web Tokens
Что такое JWT?
JSON Web Token (JWT) — это открытый стандарт (RFC 7519), определяющий компактный, самодостаточный способ безопасной передачи информации между сторонами в виде объекта JSON. JWT являются доминирующим форматом токенов в современных веб-приложениях и используются для всего: от аутентификации пользователей и авторизации API до безопасного обмена данными между микросервисами.
Как работает аутентификация JWT
Аутентификация JWT следует модели без сохранения состояния (stateless), которая устраняет необходимость в хранении сессий на стороне сервера. Понимание этого процесса является ключом к пониманию того, почему JWT стали выбором по умолчанию для безопасности современных API.
Процесс аутентификации
- Пользователь входит в систему — Клиент отправляет учётные данные (имя пользователя и пароль) на сервер аутентификации.
- Сервер создаёт JWT — Сервер проверяет учётные данные, создаёт JWT, содержащий идентификационные данные и разрешения пользователя, подписывает его секретным или приватным ключом и возвращает клиенту.
- Клиент сохраняет токен — Клиент сохраняет JWT, обычно в localStorage, sessionStorage или в HTTP-only cookie.
- Клиент отправляет токен с каждым запросом — При каждом последующем запросе к API клиент включает JWT в заголовок
Authorizationпо схеме Bearer:Authorization: Bearer <token>. - Сервер проверяет токен — Сервер проверяет подпись JWT, время истечения и извлекает claims пользователя для авторизации запроса.
- Поиск сессии не требуется — Поскольку JWT содержит всю необходимую информацию, серверу не нужно обращаться к базе данных или кэшу для идентификации пользователя.
Почему это важно
Традиционная аутентификация на основе сессий хранит идентификаторы сессий в памяти или базе данных сервера. Каждый аутентифицированный запрос требует поиска. JWT устраняют этот поиск — сам токен подтверждает личность пользователя. Это делает системы на основе JWT изначально масштабируемыми, поскольку любой сервер в кластере может проверить токен без общего состояния сессии.
JWT и аутентификация на основе сессий
| Аспект | Аутентификация JWT | Аутентификация на основе сессий | |--------|--------------------|------------------------------| | Хранение | На стороне клиента (в токене) | На стороне сервера (в памяти или БД) | | Масштабируемость | Не требует общего хранилища сессий | Требует общего хранилища сессий между экземплярами | | Кросс-доменность | Естественно работает между доменами | Сложно делиться сессиями | | Мобильные устройства | Да (cookies не требуются) | Требует поддержки cookies | | Отзыв | Сложно (до истечения токена) | Легко (удалить сессию из хранилища) | | Размер полезной нагрузки | Больше на каждый запрос (токен в заголовке) | Минимальный (только ID сессии) |
Почему JWT используется для безопасности API
Характеристики, которые делают JWT подходящим для аутентификации, также делают его идеальным для защиты API.
Без сохранения состояния и масштабируемость
Каждый JWT несёт всю информацию, необходимую серверу для авторизации запроса. Нет базы данных сессий для запроса, нет кэша для проверки, нет состояния для синхронизации между серверами. Балансировщики нагрузки могут направлять запросы на любой экземпляр сервера без координации.
Кросс-доменность и кросс-ориджинность
JWT естественно работает между разными доменами и источниками (origins). Токен, выданный auth.example.com, может использоваться для доступа к api.example.com и admin.example.com. Это делает JWT основой систем единого входа (SSO).
Детальная авторизация
Полезная нагрузка JWT может включать пользовательские claims для ролей, разрешений и членства в организациях:
{
"sub": "user_abc123",
"role": "admin",
"permissions": ["read:users", "write:users", "delete:users"],
"org_id": "org_xyz789",
"iat": 1516239022,
"exp": 1516325422
}
Сервер API считывает эти claims непосредственно из токена без каких-либо дополнительных запросов.
JWT для единого входа (SSO)
Единый вход — один из наиболее распространённых сценариев использования JWT. В типичной архитектуре SSO:
- Пользователь входит в систему через поставщика идентификации (IdP) — такого как Auth0, Okta или Keycloak.
- IdP выпускает JWT, подписанный своим приватным ключом.
- Пользователь предъявляет этот JWT нескольким приложениям.
- Каждое приложение проверяет подпись с помощью открытого ключа IdP.
- Каждое приложение доверяет токену без обращения к IdP при каждом запросе.
Эта модель позволяет одному входу предоставить доступ к десяткам сервисов — электронной почте, файловому хранилищу, управлению проектами, HR-системам — без реализации каждым сервисом собственного процесса входа.
Лучшие практики безопасности JWT
Хотя JWT обеспечивает прочную основу для безопасности API, правильная реализация крайне важна.
Используйте короткоживущие токены
Устанавливайте claim exp (expiration) на короткий срок — от 15 минут до 1 часа для токенов доступа. Используйте более долгоживущие refresh-токены (дни или недели) для получения новых токенов доступа без повторной аутентификации пользователя.
Всегда используйте HTTPS
JWT не шифрует свою полезную нагрузку. Любой, кто перехватит токен, может декодировать и прочитать его содержимое. Всегда передавайте JWT по HTTPS для предотвращения перехвата.
Проверяйте всё
Всегда проверяйте подпись, убедитесь, что срок действия токена не истёк, подтвердите, что aud (audience) соответствует вашему приложению, и отклоняйте токены с неожиданными алгоритмами.
Храните токены безопасно
На стороне клиента храните JWT в HTTP-only cookies, когда это возможно, или в памяти для одностраничных приложений. Избегайте localStorage для токенов, предоставляющих доступ к конфиденциальным данным.
Распространённые заблуждения о JWT
«JWT зашифрован.» — Нет. JWT подписан, а не зашифрован. Полезная нагрузка закодирована в base64url, что является обратимым. JWE (JSON Web Encryption) обеспечивает шифрование, но это отдельная спецификация, не охватываемая стандартным JWT.
«JWT предотвращает CSRF.» — Не сам по себе. JWT в заголовке Authorization помогает, но если токен находится в cookie, защита от CSRF всё ещё необходима.
«JWT только для аутентификации.» — JWT используется для аутентификации, но также для обмена данными авторизации, сессий без сохранения состояния и безопасного обмена информацией между сервисами.
Декодируйте и исследуйте JWT онлайн
Используйте инструмент JWT decoder для анализа любого JSON Web Token. Вставьте ваш токен и мгновенно увидите декодированный заголовок, полезную нагрузку и алгоритм подписи. Инструмент помогает понять, какие данные несут ваши токены, и убедиться, что они правильно структурированы.