Что такое jwt авторизация

Пять простых шагов для понимания JSON Web Tokens (JWT)

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Представляю вам мой довольно вольный перевод статьи 5 Easy Steps to Understanding JSON Web Tokens (JWT). В этой статье будет рассказано о том, что из себя представляют JSON Web Tokens (JWT) и с чем их едят. То есть какую роль они играют в проверке подлинности пользователя и обеспечении безопасности данных приложения.

Для начала рассмотрим формальное определение.

JSON Web Token (JWT) — это JSON объект, который определен в открытом стандарте RFC 7519. Он считается одним из безопасных способов передачи информации между двумя участниками. Для его создания необходимо определить заголовок (header) с общей информацией по токену, полезные данные (payload), такие как id пользователя, его роль и т.д. и подписи (signature).
Кстати, правильно JWT произносится как /dʒɒt/

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Приложение использует JWT для проверки аутентификации пользователя следующим образом:

Структура JWT

Шаг 1. Создаем HEADER

Хедер JWT содержит информацию о том, как должна вычисляться JWT подпись. Хедер — это тоже JSON объект, который выглядит следующим образом:

Шаг 2. Создаем PAYLOAD

Payload — это полезные данные, которые хранятся внутри JWT. Эти данные также называют JWT-claims (заявки). В примере, который рассматриваем мы, сервер аутентификации создает JWT с информацией об id пользователя — userId.

Мы положили только одну заявку (claim) в payload. Вы можете положить столько заявок, сколько захотите. Существует список стандартных заявок для JWT payload — вот некоторые из них:

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

Шаг 3. Создаем SIGNATURE

Подпись вычисляется с использование следующего псевдо-кода:

Алгоритм base64url кодирует хедер и payload, созданные на 1 и 2 шаге. Алгоритм соединяет закодированные строки через точку. Затем полученная строка хешируется алгоритмом, заданным в хедере на основе нашего секретного ключа.

Шаг 4. Теперь объединим все три JWT компонента вместе

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

Вы можете попробовать создать свой собственный JWT на сайте jwt.io.
Вернемся к нашему примеру. Теперь сервер аутентификации может слать пользователю JWT.

Как JWT защищает наши данные?

Очень важно понимать, что использование JWT НЕ скрывает и не маскирует данные автоматически. Причина, почему JWT используются — это проверка, что отправленные данные были действительно отправлены авторизованным источником. Как было продемонстрировано выше, данные внутри JWT закодированы и подписаны, обратите внимание, это не одно и тоже, что зашифрованы. Цель кодирования данных — преобразование структуры. Подписанные данные позволяют получателю данных проверить аутентификацию источника данных. Таким образом закодирование и подпись данных не защищает их. С другой стороны, главная цель шифрования — это защита данных от неавторизованного доступа. Для более детального объяснения различия между кодированием и шифрованием, а также о том, как работает хеширование, смотрите эту статью. Поскольку JWT только лишь закодирована и подписана, и поскольку JWT не зашифрована, JWT не гарантирует никакой безопасности для чувствительных (sensitive) данных.

Шаг 5. Проверка JWT

В нашем простом примере из 3 участников мы используем JWT, который подписан с помощью HS256 алгоритма и только сервер аутентификации и сервер приложения знают секретный ключ. Сервер приложения получает секретный ключ от сервера аутентификации во время установки аутентификационных процессов. Поскольку приложение знает секретный ключ, когда пользователь делает API-запрос с приложенным к нему токеном, приложение может выполнить тот же алгоритм подписывания к JWT, что в шаге 3. Приложение может потом проверить эту подпись, сравнивая ее со своей собственной, вычисленной хешированием. Если подписи совпадают, значит JWT валидный, т.е. пришел от проверенного источника. Если подписи не совпадают, значит что-то пошло не так — возможно, это является признаком потенциальной атаки. Таким образом, проверяя JWT, приложение добавляет доверительный слой (a layer of trust) между собой и пользователем.

В заключение

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

Что дальше?

Источник

JWT простым языком: что такое JSON токены и зачем они нужны

Краткий, но исчерпывающий обзор JWT и его возможностей. JSON токены, их структура, построение и распространенные способы использования.

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

После беглого знакомства с JSON web tokens может сложиться впечатление, что они встроены в современные механизмы авторизации и аутентификации, такие как OAuth или OpenID. Однако это не совсем так. JSON токены действительно используются в этих системах, но не являются их частью. Более того, сфера их использование гораздо шире авторизации.

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

Что такое JWT?

Если обратиться с этим запросом в Google, вероятнее всего, он выдаст что-то подобное:

Все эти определения верны, но они звучат чересчур научно и абстрактно. Попробуем дать JWT собственное описание.

Веб-токен JSON, или JWT (произносится «jot»), представляет собой стандартизированный, в некоторых случаях подписанный и/или зашифрованный формат упаковки данных, который используется для безопасной передачи информации между двумя сторонами.

Проанализируем эту формулировку.

Формат упаковки данных

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

Десериализованная форма

В несериализованном виде JWT состоит из заголовка и полезной нагрузки, которые являются обычными JSON-объектами.

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

Если JWT подписан и/или зашифрован, в заголовке указывается имя алгоритма шифрования. Для этого предназначена заявка alg :

Заявки бывают служебными и пользовательскими. Первые обычно являются частью какого-либо стандарта, например, реестра JSON Web Token Claims, и имеют определенные значения. Наиболее распространенные служебные заявки:

Полный список заявок приведен в реестре.

Неподписанные JSON токены

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

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

В спецификации OpenID можно ознакомиться с полным списком заявок.

Сериализованные JSON токены

JSON web token в сериализованной форме – это строка следующего формата:

[ Header ].[ Payload ].[ Signature ]

Заголовок (header) и полезная нагрузка (payload) присутствуют всегда, а вот подпись (signature) может отсутствовать.

Пример компактной формы:

Она получена из следующих данных:

Сериализация

На рисунке изображен процесс сериализации неподписанного токена:

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

В коде это можно представить следующим образом:

Чтобы декодировать токен, достаточно просто разбить его по точкам и конвертировать заголовок и полезную нагрузку из кода base64url обратно в строку. Пример кода, который это делает:

Использование библиотек

Разумеется, JSON токены не кодируются вручную. Существует множество библиотек, предназначенных для этого. Например, jsonwebtoken:

Этот код создает подписанный JWT с использованием секретного слова. Затем он проверяет подлинность токена и декодирует его, применяя тот же секрет. Подпись и другие механизмы безопасности будут разобраны далее.

Приложения

Пора переходить к практическому применению JWT. В принципе, JSON токены может использовать любой процесс, связанный с обменом данных через сеть. Например, простое клиент-серверное приложение или группа из нескольких связанных серверов и клиентов. Отличным примером сложных процессов со множеством потребителей данных служат фреймворки авторизации, такие как AuthO и OpenID.

Чаще всего используются клиентские сеансы без сохранения состояния. При этом вся информация размещается на стороне клиента и передается на сервер с каждым запросом. Именно здесь используется JSON web token, который обеспечивает компактный и защищенный контейнер для данных.

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

Серверные сессии с хранением состояния

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

Многие годы для этого использовались сеансы на стороне сервера. Пользовательские данные при этом хранятся в файловой системе, базе данных или memcache. Вот для примера список различных сессионных хранилищ известного модуля Node.js express-session.

Чтобы связать данные на сервере с клиентскими запросами, идентификатор сеанса помещается в файлы cookie или сохраняется с помощью других HTTP-функций. Он отправляется на сервер с каждым запросом и используется для поиска сеанса этого конкретного клиента. Важный момент: в файлах cookie сохраняется только идентификатор, но не сама информация.

Данные сеанса представляют собой определенное состояние, поэтому мы говорим о сессиях с хранением состояния.

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

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

Сеансы на стороне клиента

В отличие от серверных сессий, данные клиентских сеансов хранятся на машине пользователя и отправляются с каждым запросом. Один из способов реализации этого механизма – использование файлов cookie. В них можно хранить не только идентификатор сеанса, но и сами данные. Куки-файлы очень удобно использовать, поскольку они автоматически обрабатываются веб-браузерами. Однако это не единственный способ передавать информацию сеанса. Это также можно делать через HTTP-заголовки, чтобы избежать проблем с CORS, или с помощью URL-параметров.

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

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

Впрочем, у сеансов на стороне клиента также есть свои минусы. Например, приложение может требовать большого объема пользовательских данных, и их придется отправлять туда-обратно для каждого запроса. Это может даже перекрыть все преимущества простоты и масштабируемости. Таким образом, в реальном мире приложения зачастую совмещают клиентские и серверные сеансы.

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Защита веб-токенов

Как уже упоминалось выше, JWT использует два механизма для защиты информации: подписи и шифрование. Их описывают стандарты безопасности JSON Web Signature (JWS) и JSON Web Encryption (JWE).

Подпись JWT

Цель подписи заключается в том, чтобы дать возможность одной или нескольким сторонам установить подлинность токена. Помните пример подделки идентификатора пользователя из cookie для получения доступа к чужой учетной записи? Токен можно подписать, чтобы проверить, не были ли изменены данные, содержащиеся в нем. Однако подпись не мешает другим сторонам читать содержимое JWT, это уже дело шифрования. Подписанный веб-токен известен как JWS (JSON Web Signature). В компактной сериализованной форме у него появляется третий сегмент – подпись.

Самый распространенный алгоритм подписи – HMAC. Он объединяет полезную нагрузку с секретом, используя криптографическую хеш-функцию (чаще всего SHA-256). С помощью полученной уникальной подписи можно верифицировать данные. Это схема называется разделением секрета, поскольку он известен обеим сторонам: создателю и получателю. Таким образом, и тот, и другой могут генерировать новое подписанное сообщение.

Другой алгоритм подписи – RSASSA. В отличие от HMAC он позволяет принимающей стороне только проверять подлинность сообщения, но не генерировать его. Алгоритм основан на схеме открытого и закрытого ключей. Закрытый ключ может использоваться как для создания подписанного сообщения, так и для проверки. Открытый ключ, напротив, позволяет лишь проверить подлинность. Это важно во многих сценариях подписки, таких как Single-Sign On, где есть только один создатель сообщения и много получателей. Таким образом, никакой злонамеренный потребитель данных не сможет их изменить.

Шифрование

В отличие от подписи, которая является средством установления подлинности токена, шифрование обеспечивает его нечитабельность.

Зашифрованный JWT известен как JWE (JSON Web Encryption). В отличие от JWS, его компактная форма имеет 5 сегментов, разделенных точкой. Дополнительно к зашифрованному заголовку и полезной нагрузке он включает в себя зашифрованный ключ, вектор инициализации и тег аутентификации.

Подобно JWS, он может использовать две криптографические схемы: разделение секрета и открытый/закрытый ключи.

Схема разделенного секрета аналогична механизму подписки. Все стороны знают секрет и могут шифровать и дешифровать токен.

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

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

Источник

JWT — как безопасный способ аутентификации и передачи данных

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

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

В этой статье разберу, что такое Access токен, Refresh токен и как с ними работать.

Для дальнейших разборов будет использован токен:

После того, как посетитель прошел авторизацию в нашей системе, указав свой логин и пароль, система выдает ему 2 токена: access token и refresh токен.

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

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

Это можно проверить прям в браузере, выполнив в консоле или js коде:

Вторым блоком идет eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODEzNTcwMzl9

Это есть полезные данные, так же закодированные в Base64. После раскодирования получим:

Поскольку необходимо ограничивать токен по времени, поле exp обязательно. По нему можно проверить, актуален ли токен или нет.

Она получается примерно следующим образом:

Берем заголовок, например <"alg":"HS256","typ":"JWT">и кодируем его в base64, получаем ту самую часть eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Тоже самое проделываем с данными eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODEzNTcwMzl9

После этого склеиваем их и получаем eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODEzNTcwMzl9

Далее эти данные шифруем с помощью нашего алгоритма HMAC-SHA256 и ключа.

Для проверка токена необходимо проделать ту же операцию.

Как только время выйдет, пользователю снова придется проходить авторизацию. Так вот чтобы этого избежать, существует Refresh токен. С помощью него можно продлить Access токен.

У него, обычно, нет какой-то структуры и это может быть некая случайная строка.

Для проекта odo24.ru я использовал следующий подход.

Генерируется Access токен и после случайная строка, например T6cjEbghMZmybUd_fhE

С нашего нового Access токена eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODEzNTcwMzl9.E4FNMef6tkjIsf7paNrWZnB88c3WyIfjONzAeEd4wF0 беру последние шесть знаков, получаю Ed4wF0

Склеиваю и получаю рефреш токен T6cjEbghMZmybUd_fhEEd4wF0

Это сделано для привязки Access токена к Refresh. Для получения новых токенов необходимо передать эти два токена. Делается проверка на их связку и только после валидируется Access токен. Если и второй этап прошел успешно, тогда получаем с базы данных по текущему user_id рефреш токен и сверяем с тем, что к нам пришел. Если они совпадают, тогда генерируются новые токены и в базе данных обновляется Refresh токен на новый.

В моем случае я разделил оба токена и храню в разных местах. Access токен нужен только для идентификации пользователя и на клиенте (JS) он не нужен, поэтому он передается в Cookie (http only).

Refresh токен хранится в LocalStorage и используется только когда Access токен перестал быть актуальным.

Представим ситуацию, когда у нас каким-то образом украли Access токен. Да, это уже плохо и где-то у нас брешь в безопасности. Злоумышленник в этом случае сможет им воспользоваться не более чем на 15-30 минут. После чего токен «протухнет» и перестанет быть актуальным. Ведь нужен второй токен для продления.

Если украли Refresh токен, то без Access токена (который недоступен в JS) продлить ничего нельзя и он оказывается просто бесполезным.

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

Дата содержит год, месяц, день, час и минуты. Хранится в ASCII

Кодирование даты на Golang:

Всю реализацию на Go можно изучить на Github-е

В этой статье попытался рассказать о взаимодействии двух токенов и как ими пользоваться. В сети достаточно много информации о Access токенах, однако мало, как мне показалось, информации о Refresh токенах.

Источник

Полное руководство по управлению JWT во фронтенд-клиентах (GraphQL)

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Jun 23, 2020 · 14 min read

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

JWT (JSON Web Token, произносится как ‘jot’ [джот]) становится популярным способом управления аутентификацией. Эта статья ставит целью развенчать мифы о стандарте JWT, рассмотреть его плюсы и минусы, а также познакомиться с лучшими методиками реализации JWT на стороне клиента с учётом безопасности. Несмотря на то, что здесь мы работали над примерами с помощью клиентов GraphQL, используемые принципы применимы к любому другому фронтенд-клиенту.

Знакомство: что такое JWT?

В целях аутентификации JWT выступает в р оли токена, выдаваемого сервером. Этот токен содержит относящееся к конкретному пользователю информационное наполнение в формате JSON. Клиенты могут использовать токен при взаимодействии с API (отправляя его как HTML-заголовок), чтобы API могли идентифицировать пользователя и выполнить соответствующее ему действие.

Но разве не может клиент просто создать случайное информационное наполнение и выдать себя за пользователя?

Хороший вопрос! Именно поэтому JWT также содержит подпись, которая создаётся сервером, выдавшим токен (предположим, конечной точкой вашей авторизации в системе). Любой другой сервер, получающий этот токен, может независимо проверить подпись, чтобы убедиться в подлинности информационного наполнения JSON и в том, что это наполнение было создано уполномоченным источником.

Но что если у меня есть действительный и подписанный JWT, а кто-то украдёт его из клиента? Смогут ли они постоянно использовать мой JWT?

Да. Если JWT будет украден, то вор сможет продолжать его использовать. API, принимающий JWT, выполняет самостоятельную проверку, не зависящую от его источника, следовательно сервер API никак не может знать о том, что этот токен был украден. Именно поэтому у JWT есть значение срока годности, которое намеренно создается коротким, и довольно часто его длительность определяется всего в 15 минут. Но при этом также нужно следить за тем, чтобы не произошло утечки JWT.

Из этих двух фактов формируются практически все особенности управления JWT. Т.е. мы стараемся избежать кражи, а если она всё же происходит, то нас спасает короткое время действия токенов.

Именно поэтому очень важно не хранить JWT на клиенте, например в куки или локальном хранилище. Поступая так, вы делаете своё приложение уязвимым для атак CSRF и XSS, которые при помощи вредоносных форм или скриптов могут использовать или украсть ваш токен, благоприятно размещённый в куки или локальном хранилище.

Есть ли у JWT какая-то конкретная структура?

В сериализованном виде JWT выглядит примерно так:

Если вы раскодируете этот base64, то получите JSON в виде 3 важных частей: заголовка, информационного наполнения и подписи.

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Сериализованная форма будет иметь следующий формат:

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

Вот упрощённая схема, демонстрирующая, как JWT выдаётся ( /login ), а затем используется для совершения вызова API к другому сервису ( /api ):

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Выглядит сложновато. Почему бы мне не придерживаться старых добрых токенов сессии?

Это уже наболевшая тема интернет-форумов. Мы коротко и категорично отвечаем, что бэкенд-разработчикам нравится использовать JWT по следующим причинам:

b) отсутствие необходимости в централизованной базе данных токенов.

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

Именно поэтому разработчики API ценят JWT, а мы (с клиентской стороны) должны разобраться, как его использовать. Как бы то ни было, если вы можете обойтись токеном сессии, выданным вашим любимым монолитным фреймворком, то всё у вас в порядке и нет нужды в JWT.

Вход в систему

Теперь, когда у нас есть базовое понимание JWT, давайте создадим простой процесс входа в систему и извлечём JWT. Вот что у нас должно получиться:

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Процесс входа в систему принципиально не отличается от того, с которым вы сталкиваетесь регулярно. Например, вот форма авторизации, которая отправляет имя пользователя/пароль в конечную точку аутентификации и получает в ответ JWT-токен. Это может быть авторизация с помощью внешнего провайдера, шаг OAuth или OAuth2. Главное, чтобы в ответ на завершающий шаг входа в систему клиент получил JWT-токен.

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

Вот как может выглядеть обработчик handleSubmit для кнопки входа в систему:

Итак, мы получили токен, где же нам теперь его хранить?

Нам необходимо где-то сохранить полученный JWT-токен, чтобы иметь возможность перенаправлять его нашему API в качестве заголовка. Вы можете соблазниться мыслью поместить его в локальное хранилище (localstorage). Не стоит этого делать, т.к. оно уязвимо для XSS-атак.

Может сохранить его в куки?

Куки, созданная в клиенте для сохранения JWT, также будет уязвима для XSS. Если JWT может быть считан на клиенте из JavaScript вне вашего приложения — то может быть и украден. Вы можете подумать, что поможет куки HttpOnly (создаваемая сервером, а не клиентом), но куки уязвимы к CSRF-атакам. Важно отметить, что HttpOnly, а также чувствительные политики CORS не могут предотвратить CSRF-атаки входа, и использование куки требует надлежащей стратегии по борьбе с ними.

Обратите внимание, что новая спецификация SameSite Cookie, которая получает повышенную поддержку в большинстве браузеров, будет создавать куки на основе подходов, защищённых от CSRF-атак. Это решение может не сработать, если ваши серверы Auth и API размещены на разных доменах, но в противном случае такой вариант должен вполне подойти.

Где же тогда нам его хранить?

На данный момент мы будем хранить токен в памяти (и перейдём к постоянным сеансам в следующем разделе).

Теперь, когда у нас есть токен, что нам с ним делать?

Как нам проверить, авторизован ли пользователь?

Настройка клиента

Теперь пришло время настроить наш клиент GraphQL. Замысел в том, чтобы получить токен из установленной нами переменной и, если он там, передавать его нашему клиенту GraphQL.

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Как видно из этого кода, если есть токен, то он передаётся каждому запросу в качестве заголовка.

Но что случится, если токена не будет?

Всё зависит от потока выполнения в вашем приложении. К примеру, вы можете перенаправлять пользователя назад на страницу авторизации:

А если токен истекает в процессе его использования?

Предположим, наш токен действителен только 15 минут. В этом случае при его истечении мы, вероятно, получим ошибку от API, отрицающего наш запрос (например, 401: Unauthorized ). Помните, что каждый сервис, умеющий использовать JWT, может независимо верифицировать его и проверить, истёк ли срок действия.

Давайте добавим в наше приложение обработку ошибок, чтобы разобраться с подобными случаями. Мы напишем код, который будет выполняться для каждого ответа API, проверяя его на ошибку. Когда мы получим от API ошибку об истечении/недействительности токена, мы запустим процесс выхода из системы или перенаправимся к процессу входа в неё.

Вот как выглядит код, если мы используем клиент Apollo:

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

Выход из системы

При использовании JWT “logout” просто стирает токен на стороне клиента, после чего он уже не может быть использован в последующих вызовах API.

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

Значит вызова API /logout не существует?

Что делать, если мне нужно обеспечить невозможность продолжения использования токена?

Поэтому важно определять краткосрочные значения срока действия JWT. По этой же причине нам ещё более важно обеспечить таким образом защиту JWT от кражи. Токен действителен (даже после его удаления на клиенте), но только в течение короткого промежутка времени, что снижает вероятность его использования злоумышленниками.

Разве наличие чёрного списка не исключает преимущество JWT, гласящее о необязательности центрального хранилища?

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

Что произойдёт, если я авторизован на нескольких вкладках?

Один из способов разрешения этой ситуации заключается во введении в локальном хранилище глобального слушателя событий. При каждом обновлении этого ключа logout в локальном хранилище для одной вкладки, слушатель сработает и на других вкладках, также запустив ‘logout’ и перенаправив пользователей на экран входа в систему.

Теперь при выходе нам нужно совершить два действия:

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

Это работает для вкладок, но как мне принудительно закрыть сессии на разных устройствах?

Эту тему мы рассмотрим в одном из следующих разделов.

Фоновое обновление

Существует две главных проблемы, с которыми могут столкнуться пользователи нашего JWT-приложения:

Для решения этих проблем большинство JWT-провайдеров предоставляют токен обновления, который имеет два свойства:

Как работает обновляемый токен?

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

На клиенте до момента истечения текущего токена мы подключаем наше приложение, чтобы сделать конечную точку refresh_oken и получить новый JWT.

Как осуществляется безопасное хранение токена обновления на клиенте?

Какой же из способов сохранения JWT-сессии в итоге мы считаем лучшим?

Ответить можно в виде следующего уравнения: сохранение JWT-токена в локальном хранилище (уязвимом для XSS) Как же выглядит новый процесс “авторизации”?

Ничего особо не меняется, за исключением того, что токен обновления отправляется вместе с JWT. Давайте ещё раз взглянем на диаграмму процесса авторизации, но теперь уже с функциональностью refresh_token :

Что такое jwt авторизация. Смотреть фото Что такое jwt авторизация. Смотреть картинку Что такое jwt авторизация. Картинка про Что такое jwt авторизация. Фото Что такое jwt авторизация

А как выглядит фоновое обновление?

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *