другое,

JWT - коротко о главном

Oct 19, 2021 · 4 мин. на прочтение
JWT - коротко о главном
Поделиться

В этой статье я коротко расскажу о том, что такое JWT (JSON WEB TOKEN) и как он применяется в процессе аутентификации и авторизации

Есть такая штука, называется JWT - JSON Web Token. По сути это способ (стандарт) обернуть данные (payload) в подписанный пакет. В основном это используется для обмена данными, например авторизационными. Рассмотрим как это работает на простом примере авторизации.

  1. Пользователь аутентифицируется с использованием login/пароля (АУТЕНТИФИКАЦИЯ)
  2. В ответ получает jwt - json web token. Далее по тексту jwt-токен или просто “токен”.
  3. Когда пользователь хочет получить доступ к ресурсу, он отправляет токен
  4. Сервер проверяет валидность токена и предоставляет доступ к ресурсу (АВТОРИЗАЦИЯ)

Важно понимать, что токен не содержит в себе никакой секретной информации. Чаще всего туда помещают информацию о пользователе (id, username, email, role). Эта информация может быть прочитана кем угодно. Подписывается токен для того, чтобы убедиться в том, что информация в токене не была подделана/изменена. Подписан токен может либо закрытым ключом, либо парой открытым/закрытым ключом.

JWT похож на SAML, но гораздо проще. На картинке ниже проиллюстрировано то, как выглядит JWT-токен, подписанный парой ключей, открытым и закрытым. JWT токен состоит из заголовка, данных и подписи (“HEADER”+”PAYLOAD”+”SIGNATURE”).

jwt-quick-start/1.png

Как видите, структура JWT-токена очень проста. Ниже показано сравнение того, как выглядит JWT-токен и SAML-сообщение.

jwt-quick-start/2.png

Рассмотрим принцип использования JWT, описанный в начале, более подробно, приблизив его к реальности.

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

1. Пользователь аутентифицируется с использованием логин/пароля (АУТЕНТИФИКАЦИЯ)

Если говорить про WEB, то как правило пользователь заходит на сайт (клиент) и вводит логин пароль в форму авторизации. Клиент отправляет авторизационные данные серверу аутентификации, задача которого проверить, что пользователь является тем, за кого он себя выдаёт сверив пару логин/пароль с тем, что находится в его базе данных. И в зависимости от результата проверки возвращает положительный или отрицательный ответ клиенту (web-приложению, куда пользователь ввёл логин/пароль). Этот процесс называется аутентификация. Не путать с авторизацией.

2. Пользователь получает JWT-токены

Если пользователь успешно прошёл процесс аутентификации, то есть ввёл действительные логин и пароль, то клиент, получив положительный ответ от сервера аутентификации запрашивает у сервера, который выдаёт токен, пару токенов - AccessToken и RefreshToken. Далее я объясню, откуда вдруг взялся RefreshToken и зачем он нужен.

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

Для хранения токена очень важно использование флага HttpOnly. Иначе это считается не безопасным.

3. Когда пользователь хочет получить доступ к ресурсу, он отправляет токен

Когда пользователь хочет получить доступ к ресурсу, он отправляет запрос на сервер и передаёт AccessToken. В случае с jwt это можно сделать с использованием схемы Bearer. Для этого в HTTP заголовке передаётся ключ “Authorization” со значением, содержащим ключевое слово “Bearer” и через пробел сам токен.

Authorization: Bearer <token>

4. Сервер проверяет валидность токена и предоставляет доступ к ресурсу (АВТОРИЗАЦИЯ)

После того, как сервер получил токен, он проверяет его валидность и предоставляет доступ к ресурсу. И тут кроется самое интересное. Токен может быть не валиден по разным причинам. Например, он просрочен. Дело в том, что хранить токены длительное время - это не безопасно. В зависимости от чувствительности данных, к которым предоставляется доступ, время жизни токена может быть от нескольких секунд, до нескольких минут. В случае если токен не действителен, то сервер сообщает на клиент ошибку 401 (Unauthorized Error). В таком случае клиент может попросить пользователя ещё раз ввести логин пароль. Но чтобы не делать это слишком часто, придумали RefreshToken. Время жизни RefreshToken уже гораздо больше. Например 30-60 дней.

Когда пользователь первый раз получает пару AccessToken/RefreshToken, то RefreshToken сохраняется как в базе данных на стороне сервера, вместе с id пользователя или другим уникальным идентификатором, так и на стороне клиента(пользователя). Как правило это HttpOnly-Cookie, которая хранится в браузере. Если после отправки AccessToken клиент получает ошибку 401 (Unauthorized Error), он отправляет RefreshToken на обновление токенов (/api/refresh) и после валидации RefreshToken сервер предоставляет новую пару AccessToken/RefreshToken. Клиент их сохраняет и заново отправляет AccessToken. Если на этот раз валидация прошла успешно, то сервер предоставляет доступ к запрашиваемому ресурсу.

Если же и RefreshToken не прошёл проверку, то пользователя просят заново пройти процесс аутентификации - ввести логин/пароль и заново получить пару AccessToken/RefreshToken.

На картинке показана упрощённая схема описанного процесса.

jwt-quick-start/1.png

Конечно схема авторизации может и должна быть гораздо сложнее. Серверное приложение может проверять статус активна или нет учётная запись. Позволяет ли роль пользователя получить доступ к ресурсу и т.д.. Должен быть механизм отзыва токенов. Но всё это относится к внутренней логике конкретного приложения.

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

Скоро в этом посте появится видео, в котором я покажу пример простого клиент-серверного web-приложения и наглядно продемонстрирую работу JWT.

Stay tuned…

Подпишитесь на новости
Чтобы не пропустить новые статьи. Я никогда не рассылаю спам!