Екатерина Гайнуллина, Security Vision
Что такое веб-токен
Веб-токен — это маркер доверия, цифровой идентификатор, который сервер выдает пользователю после успешной аутентификации. Получив токен, клиент передает его при каждом обращении, а сервер по этому маркеру проверяет, что запрос исходит от авторизованного пользователя. Обычно токен не содержит секретов вроде пароля. На практике же это либо случайный идентификатор сессии, либо структурированные данные с подписью, например JSON Web Token (JWT). Цифровая подпись защищает содержимое токена от подделки, а сервер может проверить подлинность токена проверкой подписи или по записи об активной сессии. По смыслу токен можно сравнить с удостоверением личности, которое подтверждает, что проверка уже пройдена и повторный ввод пароля не требуется при каждом запросе.
Примеры веб-токенов:
Session ID, или идентификатор сессии. После входа сервер создает запись сессии и отправляет клиенту уникальный идентификатор, как правило в cookie. Браузер хранит cookie и автоматически добавляет ее к каждому запросу. Сервер находит по идентификатору соответствующую сессию и тем самым узнает пользователя.
JSON Web Token, или JWT. Это токен в виде закодированного JSON из трех частей: заголовка, полезной нагрузки и подписи. Части кодируются Base64 и разделяются точками, например xxxxx.yyyyy.zzzzz. В полезной нагрузке размещают сведения о пользователе и правах доступа. JWT самодостаточен: серверу не требуется хранить состояние такой сессии, достаточно проверить подпись и сроки действия, чтобы убедиться, что токен не изменен и еще валиден.
Токены доступа и обновления в OAuth 2.0. Обычно используется пара из короткоживущего access‑токена и более долгоживущего refresh‑токена. Access‑токен дает доступ к ресурсам в течение ограниченного времени, как правило от нескольких минут до часа. Refresh‑токен хранится безопасно на стороне клиента и используется для получения нового access‑токена после истечения его срока. Такая схема позволяет не делать один долго живущий токен и при этом не заставляет пользователя часто повторять вход.
SSO токены для единого входа. Их выпускает центральный провайдер идентификации, например в формате SAML‑ассертции или JWT. После успешной аутентификации у провайдера пользователь получает токен и может обращаться к связанным приложениям без повторного ввода пароля. В токене содержатся утверждения о личности и ролях пользователя, а также метаданные о времени выдачи и сроке действия. Конкретный формат зависит от системы единого входа: используются JWT в связке с OpenID Connect или XML‑ассертции SAML.
Зачем нужны токены
Токены решают сразу несколько задач, связанных с удобством и безопасностью работы пользователей, а также с масштабируемостью веб-приложений.
Главное их преимущество заключается в удобстве, так как пользователю не нужно вводить пароль при каждом обращении к системе. Достаточно один раз пройти аутентификацию, после чего токен фиксирует факт входа и используется для всех последующих запросов. Это значительно улучшает пользовательский опыт и избавляет от постоянного подтверждения личности на каждом шаге.
Второй важной причиной применения токенов является повышение уровня безопасности. Пароль является ценной и долговечной информацией, и многократная его передача по сети увеличивает риск перехвата. В идеальной схеме пароль используется только один раз при входе, а все дальнейшие обращения удостоверяются с помощью токена. Такой токен можно сделать краткоживущим и ограниченным по правам. При его компрометации ущерб будет значительно ниже, чем при утечке пароля: доступ ограничится коротким промежутком времени или узким набором действий. Кроме того, токен легко отозвать или заменить без вмешательства пользователя, чего нельзя сделать с паролем без изменения привычного сценария работы. Токены также снижают последствия утечек: даже если они перехвачены, пароль пользователя остаётся в безопасности, и злоумышленник не сможет использовать его повторно в других системах.
С точки зрения архитектуры также особую роль играет масштабируемость. Классические сессии требуют, чтобы сервер или база данных хранили информацию обо всех активных пользователях, что при больших нагрузках становится проблемой. JWT и аналогичные решения содержат необходимые данные внутри себя, а серверу достаточно проверить подпись. Это разгружает инфраструктуру и позволяет горизонтально масштабировать систему: любой экземпляр сервера может обработать запрос, не обращаясь к общей базе сессий. Такой подход особенно полезен в распределённых архитектурах и микросервисах, где токены могут проверяться различными системами, доверяющими одному центру аутентификации.
Наконец, важна безопасность передачи. Токены часто используются в формате Bearer и передаются в заголовках HTTP-запросов, например Authorization: Bearer <token>. В сочетании с HTTPS это обеспечивает надёжную защиту при передаче по сети. В отличие от cookie, которые автоматически включаются браузером во все запросы и могут вызывать сложности с кросс-доменными взаимодействиями, токены в заголовках позволяют гибко управлять авторизацией между разными доменами и сервисами. Однако использование защищённого соединения (TLS) при этом является обязательным условием.
Основные виды веб-токенов
Существует несколько основных видов токенов, каждый со своими плюсами, минусами и областями применения:
Вид токена |
Особенности и применение |
Session ID (идентификатор сессии) |
Случайная строка, выдаётся сервером при логине. Хранится в браузере (cookie) и отправляется автоматически. На сервере соответствует записи с данными сессии пользователя. Классический вариант для веб‑сайтов: прост в реализации, но требует хранения сессий сервером (не всегда удобно для масштабирования). |
JWT (JSON Web Token) |
Структурированный токен в формате JSON, поделён на три части: header, payload, signature. Подписывается цифровой подписью (HMAC или RSA/ECDSA). В payload можно включить нужные данные (идентификатор пользователя, роли, время жизни и пр.). JWT не требует хранения на сервере — проверяется подпись, а данные берутся из самого токена. Широко используется для API и микросервисов. Следует ограничивать время жизни JWT и не класть в него секретную информацию (он не шифрован по умолчанию!). |
OAuth 2.0 Access/Refresh |
Пара токенов, работающих вместе. Access‑токен — короткоживущий (обычно 15–60 минут) токен доступа к API. Может быть JWT или просто случайной строкой (в зависимости от реализации). Refresh‑токен — более долгоживущий (часы, дни или даже месяцы) токен, хранимый безопасно, используется только для получения новых access‑токенов. Такая схема используется Google, Facebook, Яндекс и многими другими OAuth‑провайдерами: например, в Google пользовательский access‑токен живёт 1 час, после чего приложение должно обновить его через refresh‑токен. Refresh‑токен позволяет не гонять пользователя на повторный логин и при этом держать сами access‑токены короткими (для безопасности). |
SSO‑токены (SAML, Kerberos и др.) |
Токены единого входа, выпускаются центральным сервисом аутентификации. Примеры: SAML Assertion — XML‑документ с утверждениями о пользователе, подписанный сертификатом; Kerberos Ticket — токен, зашифрованный тайным ключом, который доверенные сервисы могут расшифровать и проверить. Пользователь получает такой токен от IdP (Identity Provider) после однократного ввода пароля, и далее этот токен предъявляется различным системам, которые доверяют IdP. SSO‑токены упрощают жизнь пользователям (одно логин‑подтверждение для доступа ко всем системам) и администраторам (единая точка контроля доступа). |
В реальных проектах часто используется комбинация этих подходов: например, единый вход через SSO выдаёт JWT, который затем применяется для авторизации запросов к API, а внутри мобильного приложения для продления сессии используется связка Access/Refresh. Такой многоуровневый сценарий позволяет одновременно учитывать требования безопасности, удобства и масштабируемости.
Как работают веб-токены
Процесс работы веб-токенов можно описать последовательной цепочкой действий. Сначала пользователь вводит свои учётные данные, например логин и пароль, и запрашивает доступ к системе. Сервер проверяет корректность этих данных и, если они верны, считает пользователя аутентифицированным. После этого сервер формирует токен: это может быть запись сессии с уникальным идентификатором, JWT с цифровой подписью или связка access и refresh токенов в рамках протокола OAuth. Сформированный токен отправляется клиенту либо в виде cookie, либо в теле ответа, либо в специальном заголовке.
Получив токен, клиентское приложение сохраняет его для дальнейшего использования. В браузере это чаще всего cookie, которые будут автоматически прикладываться к каждому запросу, либо локальное защищённое хранилище, если используется JWT. Правильная организация хранения критически важна, поскольку токен является ключом к учётной записи.
При каждом обращении к защищённому ресурсу клиент прикладывает токен. В случае с session id браузер отправляет cookie автоматически. JWT или access-токены обычно передаются в заголовке Authorization: Bearer <token>. Сервер получает запрос, извлекает токен и проверяет его подлинность. В случае session id сверяется наличие действительной сессии в базе, в случае JWT проверяется подпись и срок действия, а при работе с OAuth может дополнительно выполняться запрос к серверу авторизации для подтверждения валидности токена. Если токен проходит проверку, сервер считает пользователя аутентифицированным и оценивает права доступа, которые могут быть указаны в самом токене.
Так как токены имеют ограниченный срок жизни, через некоторое время они перестают действовать. Чтобы не вынуждать пользователя проходить повторный вход слишком часто, используются refresh-токены. Когда срок действия access-токена истекает, клиент обращается к специальной точке на сервере и предъявляет refresh-токен, получая взамен новый access-токен, а иногда и обновлённый refresh-токен. Этот процесс выполняется в фоновом режиме и обычно незаметен для пользователя. Однако и refresh-токены имеют конечный срок действия, после чего для продолжения работы необходимо повторно пройти аутентификацию.

Наконец, важным этапом является корректный выход из системы. При работе с классическими сессиями сервер удаляет соответствующую запись, делая токен недействительным. В случае JWT ситуация сложнее, так как такие токены не хранятся на сервере. Для их отзыва применяют механизмы чёрных списков или версионирования токенов. В сценариях OAuth сервер авторизации может пометить refresh-токен как отозванный, что исключает возможность выпуска новых access-токенов. Таким образом, процесс работы веб-токенов охватывает все стадии от первоначальной выдачи до последующего обновления и корректного завершения сессии.
Грабли и антипаттерны
Как и в любой технологии, при работе с веб-токенами существуют типичные ошибки и практики, которых следует избегать, так как они способны существенно ослабить защиту приложения.
Одной из распространённых проблем является хранение JWT в localStorage. Несмотря на удобство этого способа для разработчиков фронтенда, он делает токен уязвимым при наличии XSS-уязвимости: злоумышленник может получить доступ к содержимому хранилища и использовать токен для захвата пользовательской сессии. В отличие от cookie, для которых можно установить флаг HttpOnly, ограничивающий доступ со стороны JavaScript, в localStorage встроенной защиты нет. Более надёжным подходом является хранение токенов в защищённых HttpOnly-cookie с флагом Secure, что повышает уровень безопасности, хотя и требует дополнительной настройки CORS и CSRF-защиты.
Другой серьёзной ошибкой являются бессрочные токены. Токен без времени жизни фактически превращается в постоянный пропуск: при его компрометации злоумышленник получает неограниченный доступ. Чтобы снизить риски, каждому токену необходимо назначать срок действия. Даже refresh-токены, как правило, ограничены несколькими неделями или месяцами. Короткий срок жизни access-токена позволяет минимизировать ущерб от его утечки, а своевременное отзываемое обновление поддерживает удобство работы пользователей. Практика информационной безопасности рекомендует использовать минимально достаточные интервалы действия и отзывать токены при малейшем подозрении на компрометацию. Реальный инцидент с утечкой персонального токена администратора PyPI в 2024 году показал, что долгоживущие токены создают чрезмерные риски, и подтвердил необходимость их строгого контроля и автоматического истечения.
Ошибкой также считается чрезмерное насыщение токена данными. Если в JWT помещать полный набор прав, профиля или других объёмных сведений, токен быстро становится слишком большим. При каждом запросе он пересылается вместе с заголовками, а HTTP-заголовки имеют ограничения по размеру. Это снижает эффективность и может привести к техническим ошибкам. Оптимальный подход заключается в хранении в токене только минимально необходимой информации идентификатора пользователя, базовых ролей и кратких claim’ов. Подробные данные при необходимости должны запрашиваться отдельно. Кроме того, следует учитывать, что содержимое JWT доступно для чтения любому, кто имеет сам токен, поэтому включение в него конфиденциальной информации недопустимо.
Наконец, одной из критических ошибок является небезопасная работа с секретами, используемыми для подписания токенов. При применении симметричных алгоритмов (например, HS256) секретный ключ нередко оказывается недостаточно защищённым: его могут хранить в коде репозитория или включать в открытые конфигурации. Попадание такого ключа в руки злоумышленников означает возможность создания валидных токенов от имени сервера и полную компрометацию системы аутентификации. Зафиксированы случаи утечек JWT-секретов в публичные JavaScript-файлы и интеграционные модули сторонних сервисов. Надёжный вариант - хранение секретов только на серверной стороне, использование менеджеров секретов или переменных окружения, а также регулярная их ротация. Более безопасным решением является переход на асимметричные алгоритмы (RS256, ES256), при которых приватный ключ хранится исключительно на сервере, а клиентам передаётся лишь публичный ключ для проверки подписи.
Таким образом, внимание к способу хранения токенов, их срокам действия, структуре и защите ключей подписи является обязательным условием построения безопасной системы аутентификации.
Мифы и реальность о токенах
Существует несколько устойчивых заблуждений, связанных с применением веб-токенов.
Первый миф заключается в том, что использование JWT якобы гарантирует абсолютную безопасность. На практике это не так. Подпись токена действительно защищает его от подделки, однако если злоумышленник завладеет действующим токеном, он сможет совершать действия от имени пользователя до момента истечения срока действия. Кроме того, содержимое JWT по умолчанию не шифруется, а лишь кодируется. Любой, у кого есть токен, может декодировать его и прочитать информацию в полезной нагрузке. Это нормально и соответствует стандарту, но накладывает ограничения: в токен нельзя помещать конфиденциальные данные. Основной принцип безопасности JWT состоит не в сокрытии информации, а в невозможности её незаметной подмены без знания секретного ключа. Поэтому критически важно передавать токены только по защищённому соединению, не хранить их в небезопасных местах и ограничивать срок их действия.
Второе заблуждение связано с мнением, что refresh-токены не нужны и можно ограничиться одним access-токеном. Отказ от механизма обновления приводит либо к чрезмерно коротким срокам жизни access-токена, что ухудшает пользовательский опыт, либо к его чрезмерной «долговечности», что снижает уровень безопасности. Использование связки «короткоживущий access-токен и более длительный refresh-токен» позволяет сбалансировать удобство и защиту. При компрометации access-токена злоумышленник сможет использовать его лишь ограниченное время, а при компрометации refresh-токена администратор сможет быстро отозвать его и заблокировать дальнейший доступ.
Третье распространённое заблуждение состоит в том, что хранить токены можно где угодно. Место хранения напрямую влияет на устойчивость системы к атакам. Размещение токена в JavaScript-среде (например, в LocalStorage) делает его уязвимым к краже через XSS-атаки. Хранение в HttpOnly-cookie защищает от XSS, но повышает риск CSRF-атак, поскольку такие cookie отправляются браузером автоматически. Для защиты от CSRF существуют стандартные меры, включая атрибут SameSite у cookie, использование анти-CSRF токенов и проверку заголовков Origin. Наилучшей практикой считается хранение чувствительных токенов в HttpOnly и Secure-cookie. В тех случаях, когда применение cookie невозможно (например, в мобильных приложениях), токены следует хранить в защищённых хранилищах или в памяти, но не передавать через URL и другие потенциально небезопасные каналы.
Примеры из практики
Опыт крупных сервисов подтверждает необходимость правильной работы с токенами. Google и другие поставщики услуг используют схему OAuth 2.0, основанную на паре токенов. Пользователь получает access-токен сроком действия около часа и refresh-токен для его последующего обновления. Пока access-токен действителен, приложение может обращаться к API. После истечения срока действия access-токена оно получает новый, предъявив refresh-токен. Пользователь при этом не замечает процесса, а система сохраняет как безопасность, так и удобство работы.
GitHub применяет персональные токены доступа (Personal Access Tokens, PAT). Эти токены используются для работы с API и репозиториями без пароля и могут иметь различные области действия (scopes). PAT удобны для автоматизации, но при их компрометации злоумышленник получает все права, предоставленные токену. Поэтому GitHub позволяет ограничивать срок действия, область применения и рекомендует использовать «тонко настроенные» токены для конкретных задач. Практика показывает, что утечка PAT может иметь серьёзные последствия: в 2024 году обнаружение персонального токена администратора PyPI в публичном Docker-образе создало угрозу безопасности критичных проектов, и только своевременное его аннулирование предотвратило инцидент.
Ещё один типичный сценарий - утечки токенов в открытых репозиториях. Злоумышленники систематически отслеживают появление подобных данных на платформах вроде GitHub. Обнаруженные токены нередко используются для доступа к облачным ресурсам или сервисам, что приводит к прямым финансовым потерям или утечкам данных. Утечка секретного ключа для подписи JWT делает возможным выпуск поддельных токенов, утечка refresh-токена позволяет долгое время продлевать доступ, а компрометация session ID через XSS или незашифрованный канал фактически равносильна угону сессии.
Практика подтверждает: обращаться с токенами следует так же осторожно, как с паролями. Их не стоит хранить или публиковать в открытых источниках, передавать по незащищённым каналам или оставлять без срока действия. При подозрении на компрометацию необходимо немедленно отзывать токены и проверять логи, чтобы оценить, какие действия могли быть совершены с их использованием.
Чек-лист безопасной работы с токенами
Ниже краткий перечень рекомендаций для разработчиков и специалистов по безопасности, который поможет избежать распространённых проблем с веб‑токенами:
1.Хранение токенов.
Используйте защищённые cookie с флагами HttpOnly и Secure для веб‑приложений. Это исключает доступ к токенам из JavaScript и гарантирует их передачу только по HTTPS. Если использование cookie невозможно (например, в мобильных приложениях или сторонних REST‑клиентах), храните токены в защищённых хранилищах, предоставляемых платформой (Keychain на iOS, Keystore на Android). В крайнем случае допускается хранение в памяти, но не в долговременных открытых хранилищах. Избегайте размещения токенов в LocalStorage из‑за риска XSS.
2. Срок действия и обновление.
Устанавливайте минимально достаточный срок жизни access‑токенов и применяйте refresh‑токены для их обновления. Например, access‑токен может действовать 10–30 минут, refresh‑токен — до суток с возможностью обновления при активности. Обеспечьте корректное удаление и инвалидирование токенов при выходе пользователя из системы. Даже refresh‑токены не должны существовать бессрочно.
3.Минимизация прав.
Применяйте принцип наименьших привилегий. Каждый токен должен предоставлять доступ только к необходимым ресурсам и действиям. В OAuth используйте минимальные scopes и предпочитайте Fine‑grained токены для ограничения доступа на уровне конкретных ресурсов или операций.
4.Аудит и отзыв.
Внедрите систему журналирования действий, связанных с выдачей и использованием токенов. Логируйте идентификатор пользователя, время, устройство и ключевые действия. Реализуйте механизмы отзыва токенов: для сессий — удаление серверных записей; для JWT — чёрные списки (по jti) или ротацию ключей подписи; для OAuth — централизованный отзыв refresh‑токенов. Предусмотрите административные инструменты для принудительной аннуляции токенов при подозрении на компрометацию.
5.Передача токенов.
Никогда не передавайте токены в URL, так как они могут попасть в логи, историю браузера или заголовок Referer. Используйте заголовки (например, Authorization: Bearer <token>) или тело POST‑запроса. В сценариях OAuth применяйте одноразовые авторизационные коды вместо передачи токенов напрямую в параметрах redirect. Исключите распространение токенов через электронную почту, мессенджеры или иные небезопасные каналы.
Следуя этому чек-листу, вы закроете большинство уязвимостей, связанных с токенами, и значительно усложните жизнь злоумышленникам.
Заключение
Веб-токены сегодня являются неотъемлемым элементом современной архитектуры приложений. Независимо от того используются ли JWT, OAuth токены или идентификаторы сессий, их основная цель заключается в том, чтобы обеспечить надежное и удобное подтверждение личности пользователя без необходимости повторного ввода пароля. Токены дают возможность строить масштабируемые и распределённые системы, поддерживать единый вход и работу мобильных клиентов. Это эффективный инструмент, однако он не решает всех проблем сам по себе. Токен следует рассматривать как цифровое удостоверение личности, которое необходимо защищать столь же тщательно, как паспорт или ключ-карту. Потеря или компрометация токена означает, что доступ к системе сможет получить любой, кто им завладеет.
Security Vision желает вам безопасных внедрений и рекомендует всегда держать баланс между юзабилити и защитой. Веб-токены отличный помощник, когда применяются с умом. Теперь вы знаете о них всё, что хотели (и даже больше) – самое время применять эти знания на практике. Будьте в безопасности!
Nezd
Никогда не понимал в чем логика таких утрверждений. Почему из Telegram меня никогда не разлогинивает, а из приложения Перекрестка разлогинивает каждый раз когда я прихожу в магазин.
Я плевать хотел на супер безопасность скидочной карты, перестаньте писать эту чушь про сроки действия как что-то "правильное", это неудобно и только мешает
mshadow
А в чем чушь таких утверждений, по-моему тут все верно, токен не должен быть долгоживущим. По вашему вопросу, вы наверняка пользуетесь телегой чаще чем приложением перекресток и приложению перекресток, просто надо увеличить время жизни refresh токенов и пользователей не будет разлогинивать часто и все.