Security basics, часть 4: JWT
Статей про JWT много, но все они делают упор на авторизацию. Но JWT используется по-разному, поэтому начну с общей схемы, а потом перейду на auth.
Возьмём как пример интернет-магазин. Пользователь что-то смотрит, добавляет товары в корзину, отмечает какие-то опции.
❓ Вопрос — где хранить корзину с товарами?
🔸 На сервере
Когда клиент начинает работу с приложением, на сервере создаётся запись типа
Когда пользователь вводит логин-пароль, то получает обратно sessionID. SessionID сохраняется в cookies и автоматически добавляется в каждый запрос.
Так сервер понимает, какой пользователь прислал запрос, и с какой информацией работать.
🔸 На клиенте
Если на сервере не хранится ничего временного, то в каждом запросе клиент отправляет все нужные данные.
Браузер отправил логин-пароль — получил обратно имя пользователя и количество накопленных баллов. Сохранил у себя.
Пользователю интересны варианты доставки? В запросе отправляется город, накопленные баллы и другая информация для расчёта.
И тут вопрос — что мешает клиенту передать ложную информацию? Например, что у него 9999999 бонусных баллов.
Тут мы подходим к JWT, он гарантирует корректность присланных ранее данных. Как это работает:
1️⃣ Сервер шлёт какую-то информацию и подписывает её:
2️⃣ Клиент хранит данные у себя и обратно отправляет вместе с той же подписью:
JWT токен состоит из 3х частей:
▪️ Заголовок с алгоритмом подписи:
По сути это два JSON и строка. Чтобы передавать это как цельный объект, каждая часть кодируется Base64. Части соединяются между собой через точку в одну строку:
🔹 Пользователь вводит логин пароль
🔹 Сервер отвечает JWT токеном, внутри которого что-то вроде
🔹 Сервер валидирует подпись
Важные дополнения:
JWT ничего не шифрует, только заверяет подлинность данных. Поэтому в JWT токенах не следует передавать пароли или что-то секретное.
Важно, чтобы JWT токены хранились и передавались безопасно. Ведь если токен с авторизацией перехватит злоумышленник, то он сможет выдать себя за пользователя.
Что делать: использовать HTTPS и самые новые версии браузеров с безопасным хранением cookies.
В принципе это всё, что нужно для базового понимания JWT. Больше деталей:
▫️ JWT Security Best Practices
▫️ Спецификация JWT
Статей про JWT много, но все они делают упор на авторизацию. Но JWT используется по-разному, поэтому начну с общей схемы, а потом перейду на auth.
Возьмём как пример интернет-магазин. Пользователь что-то смотрит, добавляет товары в корзину, отмечает какие-то опции.
❓ Вопрос — где хранить корзину с товарами?
🔸 На сервере
Когда клиент начинает работу с приложением, на сервере создаётся запись типа
sessionID - { /*info*/ }Там хранится информация для текущего сеанса.
Когда пользователь вводит логин-пароль, то получает обратно sessionID. SessionID сохраняется в cookies и автоматически добавляется в каждый запрос.
Так сервер понимает, какой пользователь прислал запрос, и с какой информацией работать.
🔸 На клиенте
Если на сервере не хранится ничего временного, то в каждом запросе клиент отправляет все нужные данные.
Браузер отправил логин-пароль — получил обратно имя пользователя и количество накопленных баллов. Сохранил у себя.
Пользователю интересны варианты доставки? В запросе отправляется город, накопленные баллы и другая информация для расчёта.
И тут вопрос — что мешает клиенту передать ложную информацию? Например, что у него 9999999 бонусных баллов.
Тут мы подходим к JWT, он гарантирует корректность присланных ранее данных. Как это работает:
1️⃣ Сервер шлёт какую-то информацию и подписывает её:
"bonus":10Подпись, напомню, вычисляется из хэша данных и приватного ключа сервера.
"bonus sign":"Dfhdy76"
2️⃣ Клиент хранит данные у себя и обратно отправляет вместе с той же подписью:
"city":"moscow"3️⃣ Сервер проверяет корректность своим публичным ключом. Если клиент пришлёт "bonus" : 99999, то сервер сразу распознает обман.
"bonus":10
"bonus sign":"Dfhdy76"
JWT токен состоит из 3х частей:
▪️ Заголовок с алгоритмом подписи:
{"alg":"HS256", "typ":"JWT"}▪️ Что-то полезное:
{"bonus":10, "status":"vip"}▪️ Подпись
По сути это два JSON и строка. Чтобы передавать это как цельный объект, каждая часть кодируется Base64. Части соединяются между собой через точку в одну строку:
eyJh.TYDkwI.SflKxwRJSMИ хотя механизм универсальный, чаще всего он используется для авторизации и помогает серверу понять, кто выполняет запрос:
🔹 Пользователь вводит логин пароль
🔹 Сервер отвечает JWT токеном, внутри которого что-то вроде
"userId":34563847638🔹 Токен каждый раз передаётся в хэдере HTTP запроса
🔹 Сервер валидирует подпись
Важные дополнения:
JWT ничего не шифрует, только заверяет подлинность данных. Поэтому в JWT токенах не следует передавать пароли или что-то секретное.
Важно, чтобы JWT токены хранились и передавались безопасно. Ведь если токен с авторизацией перехватит злоумышленник, то он сможет выдать себя за пользователя.
Что делать: использовать HTTPS и самые новые версии браузеров с безопасным хранением cookies.
В принципе это всё, что нужно для базового понимания JWT. Больше деталей:
▫️ JWT Security Best Practices
▫️ Спецификация JWT