JSON Web Token (JWT): введение

Долгое время веб-куки были самым распространенным методом аутентификации пользователей. Даже сейчас этот метод хорошо работает для определенных целей. Но иногда требуется большая гибкость. Именно здесь на помощь приходит JSON Web Token. Как новый, более открытый стандарт, он все чаще используется важными веб-сайтами и приложениями. Продолжайте читать, чтобы узнать, что такое JWT, как он работает и для чего используется.

Что такое JSON Web Token?

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

JWT особенно популярен в процессах аутентификации. Его короткие сообщения могут быть зашифрованы и надежно передают информацию о том, кто является отправителем и обладает ли он необходимыми правами доступа. Сами пользователи контактируют с токеном лишь косвенно, например, когда вводят имена пользователей и пароли в маску. Реальное взаимодействие происходит между клиентом и сервером.

Как создается JWT?

Подписанный JSON Web Token состоит из трех частей, каждая из которых закодирована с помощью Base64 и разделена точкой.

HEADER.PAYLOAD.SIGNATURE

Давайте рассмотрим каждую из этих трех частей более подробно.

Заголовок

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

{ "alg": "HS256", "typ": "JWT" }

В качестве типа всегда рекомендуется использовать JWT, который относится к медиатипу IANA «application/jwt». В приведенном выше примере в качестве алгоритма подписания используется HMAC-SHA256. Другие распространенные методы шифрования включают RSA с SHA-256 («RW256») и ECDSA с SHA-256 («ES256»). Вы всегда должны использовать тот или иной вид шифрования. Однако, если данные действительно не являются конфиденциальными, вы можете ввести «none» в поле шифрования. Возможные значения стандартизированы JSON Web Encryption на основе RFC 7516.

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

Полезная нагрузка

В поле полезной нагрузки находится информация, которая будет передана приложению. В этой части определены стандарты, которые определяют, что и как передаются определенные данные. Информация представлена в виде пар ключ/значение, а ключи называются «утверждениями» в JWT. Существует три различных типа утверждений:

  • Зарегистрированные утверждения регистрируются в IANA JSON Web Token Claim Register. Их назначение определено в стандарте, например, «iss» для эмитента токена, «aud» для аудитории и «exp» для времени истечения срока действия токена. Для того чтобы длина токенов была как можно меньше, для формул используются короткие имена.
  • Публичные утверждения могут быть определены пользователем по своему усмотрению. Однако, чтобы избежать коллизий в семантике ключей, утверждения должны быть зарегистрированы в IANA JSON Web Token Claim Register или использовать имена, устойчивые к коллизиям.
  • Частные утверждения используются для индивидуального обмена информацией. В то время как публичные утверждения содержат такую информацию, как имена и адреса электронной почты, частные утверждения более уникальны. Типичная информация, которая кодируется с помощью частных утверждений, включает идентификаторы пользователей или названия конкретных отделов. При присвоении имен частным формулам важно убедиться, что не произойдет столкновения с зарегистрированными или публичными формулами.

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

Полезная нагрузка может выглядеть следующим образом:

{ "sub": "123", "name": "Alice", "exp": 30 }

Подпись

Подпись JSON Web Token создается с помощью Base64-кодирования заголовка и полезной нагрузки и указанного алгоритма подписи. Структура определяется JSON Web Signature (JWS), которая стандартизирована на основе RFC 7515. Для того чтобы подпись работала, необходимо использовать секретный ключ, который известен только издающему приложению. Подпись подтверждает, что в сообщении ничего не было изменено по пути следования. В случае токена, подписанного закрытым ключом, она также гарантирует, что отправитель является тем, за кого себя выдает.

В зависимости от того, насколько чувствительны данные, возможны различные варианты:

  • Отсутствие защиты: Как уже упоминалось выше, если данные совсем не чувствительны, в заголовке для типа шифрования можно указать значение «none». В этом случае подпись генерироваться не будет. Тогда JSON Web Token будет состоять только из заголовка и полезной нагрузки. Без какой-либо защиты полезная нагрузка может быть прочитана открытым текстом после декодирования Base64, и нет возможности проверить, пришло ли сообщение от правильного отправителя или оно было изменено по пути.
  • Подпись (JWS): Обычно достаточно проверить, поступают ли данные от правильного отправителя и не были ли они изменены. Здесь на помощь приходит JSON Web Signature, которая гарантирует, что сообщение не было изменено по пути и что оно исходит от правильного отправителя. В этом случае полезная нагрузка также может быть прочитана в виде обычного текста после декодирования Base64.
  • Подпись (JWS) и шифрование (JWE): В дополнение к JWS можно также использовать JSON Web Encryption (JWE). JWE шифрует содержимое полезной нагрузки, которое затем подписывается с помощью JWS. Для расшифровки содержимого требуется пароль или закрытый ключ. После этого проверяется отправитель, обеспечивается конфиденциальность и подлинность сообщения, а полезная нагрузка не может быть прочитана в виде обычного текста после декодирования Base64.

Благодаря шифрованию вы получите на первый взгляд случайный поток символов:

{ 7WK5T79u5mIzjIXXi2oI9Fglmgivv7RAJ7izyj9tUyQ }
Примечание

Независимо от того, какой из вышеупомянутых вариантов безопасности вы используете, для защиты данных следует также использовать SSL для связи.

Как работают JSON Web Tokens?

Давайте на примере входа пользователя в систему проиллюстрируем работу JSON Web Token. Прежде чем использовать JWT, необходимо определить секретный ключ («secret»). Как только пользователь успешно введет свои регистрационные данные, JWT будет возвращен вместе с ключом и сохранен локально. Эта передача должна происходить по HTTPS, чтобы обеспечить защиту данных.

Всякий раз, когда пользователь хочет получить доступ к защищенным ресурсам, например, к API или защищенному пути, JWT будет отправлен в качестве параметра или заголовка авторизации от агента пользователя. Партнер по коммуникации может расшифровать JSON Web Token и выполнить запрос после успешной оценки.

Примечание

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

Для чего используются JWT?

По сравнению с традиционными вариантами аутентификации и авторизации с помощью cookies, JWT имеют ряд преимуществ. Это привело к их популярности в таких контекстах, как следующие:

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

Как выглядит пример JWT?

На примере JWT давайте посмотрим, как в конечном итоге выглядит токен. Сначала возьмем пример заголовка, приведенный выше:

{
	"alg": "HS256",
	"typ": "JWT"
}

Далее, пример полезной нагрузки может быть следующим:

{
	"sub": "0123456789",
	"name": "John Doe",
	"admin": true
}

Чтобы перейти к фактической структуре JWT (три части, разделенные периодами), заголовок и полезная нагрузка должны быть закодированы в Base64. Для заголовка это будет выглядеть следующим образом:

base64Header = base64Encode(header)
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

А для полезной нагрузки это будет выглядеть следующим образом:

base64Payload = base64Encode(payload)
// eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

Теперь необходимо создать подпись. В заголовке мы указали, что следует использовать HMAC-SHA256:

signature = HS256(base64Header + '.' + base64Payload, 'secret')
// dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao

Наконец, эти три части должны быть собраны вместе и разделены точкой:

Token = base64Header + '.' + base64Payload + '.' + signature
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao

Большинство языков программирования имеют библиотеку для генерации JSON Web Tokens, что означает, что больше нет необходимости делать это вручную.

Оцените статью
cdelat.ru
Добавить комментарий