Аутентификация — первое, с чем сталкивается пользователь, и первое, что атакует злоумышленник: кража учётных данных годами входит в топ причин инцидентов в отчётах Verizon DBIR. При этом ошибки входа в систему не видны на демо и не влияют на красоту интерфейса, поэтому на приёмке проекта их легко пропустить. В этой статье разбираем два базовых механизма — сессии и JWT, объясняем, какой подходит для сайта, Telegram-бота и личного кабинета, и перечисляем типовые ошибки реализации, из-за которых аутентификация превращается в дыру в периметре.
Сессии: классический механизм с хранением на сервере
При сессионной аутентификации сервер после входа пользователя создаёт запись в хранилище (база данных, файлы или Redis) и выдаёт браузеру cookie со случайным идентификатором сессии длиной 32–64 символа. При каждом запросе браузер автоматически передаёт этот идентификатор, сервер находит сессию и понимает, кто обращается. Все данные о входе лежат на сервере, а клиент хранит лишь «ключ» — удалить доступ можно одним действием, а смену прав пользователя система увидит мгновенно. Плата за это — необходимость общего хранилища сессий, если сайт работает на нескольких серверах.JWT: токен, который сервер не хранит
JWT (JSON Web Token) — подписанная строка из трёх частей: заголовок, полезная нагрузка и подпись. В нагрузку сервер зашивает данные пользователя и срок жизни (обычно 15–30 минут), подписывает секретным ключом и отдаёт клиенту. При каждом запросе сервер просто проверяет подпись — никакого состояния хранить не нужно, токен самодостаточен. Это делает JWT стандартом для SPA на React/Vue, мобильных приложений, микросервисов и API. Обратная сторона: до истечения срока токен валиден всегда, и отозвать его без дополнительной инфраструктуры невозможно.Сравниваем по ключевым параметрам
Чтобы картина была наглядной, сведём различия в короткий список:- Выход и отзыв доступа: сессия удаляется мгновенно; для JWT нужен серверный blacklist или короткий срок жизни.
- Масштабирование: JWT не требует общего хранилища; сессиям нужен Redis или база, доступная всем серверам.
- Размер: идентификатор сессии — 32–64 байта; JWT — 500–1000 байт, которые передаются с каждым запросом.
- Хранение на клиенте: сессия живёт в httpOnly-cookie и недоступна скриптам; JWT часто кладут в localStorage, где его крадёт любая XSS-уязвимость.
- Мобильные приложения и боты: JWT удобнее — не все клиенты корректно работают с cookie.
- Цена ошибки: у сессий ниже порог промаха, у JWT выше гибкость — и выше риск неверной реализации.
Что выбрать для сайта и личного кабинета
Для классического сайта, интернет-магазина и личного кабинета с серверным рендерингом оптимальны сессии в httpOnly-cookie: простое управление доступом, мгновенный «выйти», защита от XSS по умолчанию и минимум кода. JWT оправдан, когда фронтенд — отдельное одностраничное приложение, есть мобильная версия или микросервисная архитектура: тогда рабочим стандартом становится связка «короткоживущий access-токен + refresh-токен». Гибрид тоже легитимен: сессия для веб-интерфейса и JWT для API того же продукта. Главное правило — выбирать механизм под архитектуру и требования к отзыву доступа, а не под моду в техзадании.Особый случай: Telegram-боты и Mini Apps
В ботах классической сессии нет — каждый запрос приходит с идентификатором пользователя Telegram, подлинность которого гарантирует сам мессенджер. Сложнее с Telegram Web App (Mini App): клиент присылает initData, подпись которой сервер обязан проверять через секретный ключ, выведенный из токена бота. После валидации бэкенд выпускает собственный JWT с коротким сроком жизни — никогда не доверяйте данным фронтенда без проверки подписи, иначе любой пользователь сможет отправить поддельный user_id и получить доступ к чужим данным. Тот же приём «проверили подпись Telegram → выпустили свой токен» работает для входа на сайт через бота — удобная замена логину и паролю для аудитории мессенджера.Шесть ошибок, которые превращают вход в уязвимость
Независимо от выбранного механизма, большинство инцидентов связано с типовыми промахами:- Пароли в открытом виде или через MD5. Только bcrypt, scrypt или Argon2 с индивидуальной солью — хеш MD5 подбирается за секунды на потребительской видеокарте.
- JWT в localStorage. Любая XSS-уязвимость выдаёт токен атакующему. Правильное место — httpOnly-cookie.
- Cookie без флагов. Отсутствие httpOnly, Secure и SameSite открывает путь к перехвату сессии и CSRF-атакам.
- Нет лимита попыток входа. Без rate limiting и капчи подбор пароля — вопрос времени; минимум 5 попыток с паузой и captcha.
- Предсказуемые идентификаторы сессии. ID должен генерироваться криптографическим генератором, а после входа заменяться новым — иначе возможен session fixation.
- Доверие данным без проверки. Роль и права из JWT или Telegram initData нужно перепроверять на сервере при каждом критичном действии.
JWT без отзыва —
Самая коварная ошибка — долгоживущие токены без механизма отзыва. Уволенный сотрудник или украденный токен остаётся «валидным» часами и днями: сервер честно проверяет подпись и пускает владельца внутрь. Рабочая схема — access-токен на 15–30 минут плюс refresh-токен, который хранится на сервере и отзывается одним движением. Refresh-токен при этом должен ротироваться: каждое обновление делает предыдущую копию недействительной, и кража старого токена обнаруживается сразу. Компромисс между stateless-архитектурой и контролем доступа — обязательное условие для личных кабинетов, админок и всего, где проходят деньги.Чек-лист приёмки аутентификации от подрядчика
Перед сдачей проекта попросите команду продемонстрировать следующее:- Пароли хешируются bcrypt или Argon2; в базе и логах паролей в открытом виде нет.
- Cookie передаются только по HTTPS с флагами httpOnly, Secure и SameSite.
- Работает лимит попыток входа и защита от перебора: блокировка, паузы или капча.
- Кнопка «Выйти» завершает сессию на сервере, а не просто чистит cookie в браузере.
- Срок жизни access-токенов не превышает 30 минут, refresh-токены ротируются и отзываются.
- События входа логируются: кто, когда и с какого IP — база для расследования инцидентов.
Итог простой: универсального ответа «сессии или JWT» не существует. Для классического сайта и личного кабинета надёжнее сессии в httpOnly-cookie, для SPA, мобильных приложений и Telegram Mini Apps — JWT с коротким сроком жизни и refresh-механизмом. На практике важнее не сам выбор, а качество реализации: правильно настроенные сессии безопаснее неправильно реализованного JWT. Если подрядчик не может ответить, где хранятся сессии, сколько живут токены и как отзывается доступ у пользователя — это повод заказать аудит аутентификации до запуска, а не после утечки.

