Баннер мобильный (3) Пройти тест

Что такое JSON Web Token (JWT), как он работает и зачем нужен

Как JWT обеспечивает безопасность при авторизации на сайтах и в приложениях

Разбор

8 апреля 2025

Поделиться

Скопировано
Что такое JSON Web Token (JWT), как он работает и зачем нужен

Содержание

    В современных веб-приложениях важно быстро и безопасно определять, кто именно делает запрос к серверу. Для этого чаще всего используются токены — специальные «пропуска» для пользователя. Один из самых популярных форматов таких токенов — это JWT (JSON Web Token). 

    Что такое JWT

    JSON Web Token (JWT) — это открытый стандарт (RFC 7519) для создания токенов доступа, основанный на формате JSON. Как правило, его используют в передаче данных для аутентификации или авторизации в клиент-серверных приложениях. 

    JWT разработали, чтобы усовершенствовать традиционные методы аутентификации, которые использовали сессионные токены. Основные проблемы этих подходов — сложная логика на стороне сервера при проверке токенов, а также постоянное обращение к нескольким базам данных. В результате появлялись проблемы с производительностью и масштабируемостью сервисов.

    В JWT все данные, которые нужны серверу, хранятся на стороне клиента в нем самом. Безопасность коммуникации строится на том, что токены генерируются и подписываются только со стороны веб-приложения. 

    Для более детального понимания JWT рассмотрим его структуру.

    Структура токена

    JWT состоит из трех частей: header (заголовка), payload (полезной нагрузки) и signature (криптографической подписи). Они разделены точкой, как показано в следующем примере:

    из чего состоит JWT

    Заголовок указывает тип токена и алгоритм подписи (например, HS256 или RS256).

    Полезная нагрузка — это данные, которые несут в себе определенную информацию:

    • iss (issuer) — издатель токена;
    • sub (subject) — назначение токена;
    • aud (audience) — аудитория, для которой предназначен токен;
    • exp (expire time) — срок действия токена;
    • nbf (not before) — время, до которого токен недействителен;
    • iat (issued at) — время создания токена;
    • jti (JWT id) — уникальный идентификатор токена.

    Такие блоки также называются клеймами (claims). Они могут быть обязательными или необязательными в зависимости от требований проекта. Кроме того, для специфических приложений можно добавлять пользовательские клеймы, которые будут содержать дополнительную информацию, необходимую для авторизации или других целей:

    • userId
    • name
    • role
    • email

    Криптографическая подпись создается с использованием секретного ключа, что обеспечивает целостность токена.

    Порядок создания подписи JWT:

    1. Кодирование заголовка и полезной нагрузки при помощи алгоритма base64url. 
    2. Объединение закодированных частей. Для этого используется точка («.») в качестве разделителя.
    3. Генерация подписи. Для этого может применяться, например, алгоритм HMAC-SHA256. Подпись добавляется к исходной строке также через точку.

    Особенности JWT

    Основное преимущество JWT — это его самодостаточность. В отличие от Session Authentication, где каждый запрос требует проверки в базе данных или в памяти сервера, JWT содержит всю информацию внутри себя и может быть верифицирован локально на любом сервере без дополнительных запросов.

    Другие ключевые преимущества JWT:

    • кросс-платформенность — можно использовать в разных языках программирования и средах;
    • гибкость — можно хранить дополнительную информацию о пользователе, например роли пользователя или срок действия (жизни) токена;
    • эффективность в расширенных системах — разные сервисы могут проверять токен без единого централизованного хранилища сессий.

    Однако JWT не идеален — он не поддерживает отзыв токенов по умолчанию и может быть опасен при утечке, поэтому требует осторожного применения, особенно в критически важных системах.

    Где хранится JWT? 

    Существуют различные способы хранения json web tokens. Далее представлены наиболее популярные из них.

    Способ хранения JWT
    Плюсы
    Минусы
    Веб-хранилище (localStorage или sessionStorage)
    + Браузер не будет автоматически включать что-либо из веб-хранилища в HTTP-запросы, что делает его неуязвимым для CSRF.

    + Доступ к данным может быть получен только с помощью JavaScript, работающего в том же домене, который создал эти данные.
    Недоступен для JavaScript, работающего в поддомене, который создал эти данные (значение, записанное example.com, не может быть прочитано как sub.example.com).

    Уязвим для XSS.
    Заголовок cookie
    + Неуязвим для XSS.

    + Браузер автоматически включает токен в любой запрос, который соответствует спецификации заголовка cookie (домен, путь и срок действия).

    + Файл cookie может быть создан в домене верхнего уровня и использоваться в запросах, выполняемых поддоменами.
    Уязвим для CSRF.

    Необходимо знать и всегда учитывать возможное использование файлов cookie в поддоменах.

    Выбор запросов, которые должны включать файл cookie, выполним, но сложнее.

    Можно (по-прежнему) столкнуться с некоторыми проблемами из-за небольших различий в том, как браузеры работают с файлами cookie.

    Если не быть осторожным, то можно реализовать стратегию защиты от CSRF, которая уязвима для XSS.

    Как происходит взаимодействие между клиентским JWT и сервером

    Взаимодействие между клиентом и сервером с использованием JWT (JSON Web Token) происходит по следующему алгоритму:

    1. Клиент выполняет вход, используя учетные данные и отправляя запрос на сервер.
    2. Сервер проверяет эти учетные данные. Если они действительны, сервер генерирует JWT и отправляет его обратно клиенту. При генерации JWT-токена сервер ставит подпись секретным ключом, который хранится только в веб-приложении.
    3. Клиент сохраняет JWT, обычно в локальном хранилище, и включает его в заголовок каждого последующего HTTP-запроса.
    4. Сервер, получая эти запросы, проверяет JWT. Если он действителен, клиент аутентифицирован и авторизован.
    Как работает JWT

    В зависимости от архитектуры и логики веб-приложение может одновременно использовать несколько типов токенов. Наиболее распространенные:

    • Access Token — токен доступа к информации, обычно имеет время жизни несколько минут.
    • Refresh Token — токен обновления, по которому можно только получить новую пару токенов (Access и Refresh), срок жизни измеряется днями.

    Совместное использование этих токенов позволяет реализовать безопасную и удобную систему аутентификации, при которой пользователю не требуется проходить повторную авторизацию после истечения срока действия Access Token.

    Как осуществляется передача JWT 

    Существует три популярных способа передачи JWT между клиентом и сервером. 

    1. Через HTTP-заголовок Authorization со схемой аутентификации Bearer — является наиболее безопасным и рекомендуемым способом передачи токена.

    Пример:

    GET /api/user HTTP/1.1

    Host: example.com

    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6…

    Преимущества:

    • Удобно использовать с fetch, axios, curl и другими HTTP-клиентами.
    • Можно настроить сервер для автоматической проверки заголовка.

    Безопасность:

    • Защита от CSRF, если токен не хранится в cookie.
    • Нужно защищать от XSS, если токен в localStorage/sessionStorage.
    1. В Cookie (обычно HttpOnly) — хранение и передача через cookie позволяет автоматически прикреплять токен к каждому запросу.

    Пример:

    Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6…

    Преимущества:

    • Поддерживает автоматическую отправку на каждый запрос к нужному домену.
    • Можно установить флаг HttpOnly, чтобы ограничить доступ JavaScript к токену (XSS-защита).

    Недостатки:

    • Уязвим для CSRF, если не используется SameSite=strict или CSRF-токен.
    • Меньший контроль клиента над отправкой.

    3. Через параметры URL или POST-данные — используется редко и не рекомендуется.

    Примеры:

    • https://example.com/callback?token=eyJhbGci…
    • В теле формы или JSON-объекта в POST-запросе.

    Недостатки:

    • Может попасть в логи сервера или историю браузера.
    • Повышенный риск утечки токена.

    Разбираем работу JWT на примере 

    Предположим, у нас есть веб-приложение, серверная часть которого написана на Python. Импортируем библиотеку jwt, генерируем секретный ключ и создаем логику кодирования и декодирования значений для токена.

    import jwt, datetime, secrets
    SECRET_KEY = secrets.token_hex(32)
            payload = {
                'sub': username,
                'role': role,
                'iat': datetime.datetime.utcnow(),
                'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
            }
            encode_token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
    ……………(some code)………………
    decoded_token= jwt.decode(token, SECRET_KEY, algorithms=['HS256'])

    Внешняя часть имеет страницу регистрации, личный профиль и панель администратора.

    На первой странице пользователь вводит имя пользователя и пароль, а также выбирает свою роль (обычный пользователь или администратор).

    Регистрация пользователя

    После заполнения формы на веб-сервер отправляется POST-запрос со всей необходимой информацией. На сервере генерируется JWT-токен с помощью секретного ключа и алгоритма HS256:

    (‘JWT’:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyIiwicm9sZSI6InVzZXIiLCJpYXQiOjE3NDMwMDEzMDUsImV4cCI6MTc0MzAwMzEwNX0.seqVcPftTCz5p2OzfGtRCingj4_VNyWxgrIhngNmt_U)

    После он отправляется пользователю и сохраняется в local storage:

    Local storage

    Далее для входа в личный профиль достаточно перейти на соответствующую страницу. При этом сервис сформирует и отправит GET-запрос на сервер с сохраненным токеном. После расшифровки и декодирования токена сервер верифицирует пользователя и его роль, далее предоставляет ему личный кабинет. 

    Личный кабинет

    Если обычный пользователь попытается перейти на панель администратора, появится ошибка: 

    Ошибки админ панели

    Теперь попробуем пройти этап регистрации, но уже выбрав роль «Администратор»:

    Регистрация в роли администратора

    Мы получим следующий JWT: 

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc0MzAwMjY3OCwiZXhwIjoxNzQzMDA0NDc4fQ.sA8Wpv6zK8qHXTWi_WMKaM31XY9XhUi3QDR7alxgqOU

    Теперь с таким токеном мы сможем без проблем посетить панель администратора:

    Личный кабинет админа

    Коротко о JWT

    JWT — это удобный и популярный способ передачи данных между клиентом и сервером. Он компактный, самодостаточный и хорошо справляется с задачами аутентификации, особенно в современных веб-приложениях. Благодаря своей структуре и поддержке цифровой подписи JWT обеспечивает целостность и подлинность передаваемой информации без необходимости постоянно обращаться к серверной базе данных. 

    Но не стоит думать, что JWT — это панацея от всех злоумышленников. При неправильной реализации со стороны разработчиков возрастает риск компрометации конфиденциальных данных пользователей. Поэтому при использовании JWT следует строго соблюдать рекомендации по безопасности: ограничивать срок действия токенов и применять различные алгоритмы шифрования, такие как RS256, A128CTR и другие. 

    Если все настроено грамотно, JWT станет отличным инструментом, который работает быстро, надежно и безопасно.

    Разбор

    Поделиться

    Скопировано
    0 комментариев
    Комментарии