Прекратите использовать JWT (gist от samsch)
- title
- Прекратите использовать JWT (gist от samsch)
- type
- summary
- summary
- Популярный gist с доводами против JWT для сессий: используйте cookie, а для редких сценариев с короткоживущими токенами - PASETO
- tags
- authentication, security, web
- sources
- samsch-jwt-auth-gist
- created
- 2026-04-25
- updated
- 2026-04-25
- lang
- ru
- translation_of
- samsch-jwt-auth-gist
- source_updated
- 2026-04-25
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Короткий и прямолинейный gist от пользователя GitHub samsch, доказывающий, что JWT нельзя использовать для поддержания сессий пользователей. Они для этого не создавались, у семейства этих спецификаций плохая репутация в плане безопасности, а гораздо более подходящий инструмент уже давно существует: обычные сессии на cookie. На этот gist часто ссылаются в дискуссиях о веб-аутентификации как на краткое опровержение паттерна "JWT для сессий". В качестве более подробных материалов там упоминаются развёрнутые статьи от joepie91 и Paragon Initiative.
Основной аргумент
Четыре причины против использования JWT в качестве токенов сессий, приведённые в gist'е:
- Несовпадение по времени жизни. Спецификация JWT рассчитана на очень короткоживущие токены (примерно 5 минут или меньше). Сессиям же требуется более долгий срок жизни. Попытка натянуть JWT на эту задачу вынуждает реализовывать отзыв, ротацию и управление временем жизни - возможности, которые спецификация намеренно не предоставляет.
- "Stateless"-аутентификация - это иллюзия. Нельзя безопасно реализовать аутентификацию без сохранения состояния без привлечения огромных ресурсов (списки отзыва, ротация, чёрные списки скомпрометированных токенов). Как только вы соглашаетесь с необходимостью хранилища, проще хранить всё целиком и использовать обычный идентификатор сессии. samsch даёт ссылку на соседний gist с названием "Stateless is a lie".
- JWT в качестве сессионных токенов строго хуже сессий на cookie. JWT, содержащий только ID сессии, весит больше, работает медленнее и менее гибок, чем cookie сессии. Никаких преимуществ он не даёт.
- Спецификация JWT не пользуется доверием экспертов по безопасности. Изначальная спецификация позволяла подделки с
alg: none. У семейства JOSE регулярно находили опасные подводные камни в реализациях. Вывод samsch: это должно исключать любое использование JWT в целях, связанных с безопасностью. В тексте есть ссылка на детальный разбор от Paragon.
Не храните учётные данные в localStorage
В дополнение к теме: не используйте localStorage или sessionStorage для хранения учётных данных, включая JWT. В качестве ссылки приводится статья Рэндалла Деггеса (Randall Degges) 2018 года на эту тему. Причина, по которой хранилища, доступные из JS, не могут заменить хранение сессий в cookie - уязвимость перед XSS: любой скрипт, загруженный в вашем origin, может прочитать любую запись в localStorage. До HttpOnly-cookie JavaScript добраться вообще не может.
Ответы на возражения
Gist завершается разбором трёх типичных возражений:
- Но ведь Google использует JWT! - Google не использует JWT для браузерных сессий. Они используют обычные сессии на cookie. У Google токены JWT служат транспортом для SSO - это короткоживущие bearer-токены для передачи состояния входа с одного хоста на другой. Это укладывается в разумные сценарии применения JWT, и у Google есть ресурсы безопасности, чтобы аккуратно это реализовать. Их сценарий использования JWT - не ваш.
- Но stateless же лучше! - См. дополнительный gist "Stateless is a lie". Нельзя сделать по-настоящему stateless-аутентификацию с приемлемым уровнем безопасности.
- Я не знаю, как настраивать сессии! - По сессиям мало свежих статей просто потому, что технология не нова. В большинстве веб-фреймворков middleware для сессий идёт из коробки. Для Express используйте
express-sessionс коннектором к хранилищу вродеconnect-session-knexповерх Postgres/MySQL/SQLite.
Когда JWT (или PASETO) уместны
В gist'е признаётся, что у подписанных короткоживущих токенов есть легитимные сценарии применения - транспорт для SSO, ссылки для сброса пароля, ссылки для подтверждения email, токены возможностей (capability tokens), истекающие через несколько минут. Для таких случаев samsch указывает на paseto как на более продуманного и менее опасного преемника семейства JOSE. По возможности откажитесь от JWT даже там; если не можете, выбирайте PASETO.
Почему этот gist цитируют так часто
Потому что паттерн "JWT для сессий" используется по умолчанию в бесчисленных руководствах и программах буткемпов, и аргументы против него приходится повторять снова и снова. Gist от samsch - это краткая и удобная для ссылок выжимка из более длинных материалов от joepie91 и Paragon, поэтому его из года в год отправляют в комментариях к pull request'ам и в тредах на Reddit.