Как правильно организовать обновление пар JWT + RT в API для нескольких клиентов?
Потребовалось написать общий бэк (PHP) для нескольких SPA (TS+VUE) и мобилки. В качестве механизма авторизации был выбран подход с JWT и RT токенами.
Проблема возникла на стадии проектирования логики выдачи новой пары JWT+RT. Живут токены 30 минут и 15 дней соответственно. Проблема следующая: на SPA оба токена хранятся в httpOnly куке, отправляются с каждым запросом, на стороне сервера сначала проверяется JWT, потом RT-токен при каждом запросе, требующем аутентификации. Однако в SPA при обновлении страницы могут отправиться сразу несколько запросов на разные эндпоинты, которые зависят от этого самого токена (например, получение расширенной инфы по текущему пользователю и статус текущей закладки у книги). Соответственно, в ситуации, когда в куке JWT-токен протух, на сервер приходят сразу 2 запроса с одним и тем же refresh-токеном, первый обрабатывается корректно, а вот второй запрос аутентификацию не проходит, так как во время 1 запроса refresh-токен был заменён на другой. Как наиболее корректно решать эту проблему?
Я вижу следующие решения:
1) На клиенте, например, в localstorage запихивать timestamp срока, когда JWT протухает, соответственно, при каждом запросе смотреть на эту метку, и если она приближается к сроку / уже истекла, то отправлять запрос на выдачу новой пары на соответствующий эндпоинт. Но возникает проблема с надобностью в организации очереди запросов на клиенте.
2) Мудрить что-то со временем жизни refresh-токена и количеством его использований, но тогда в принципе нарушается идея: JWT - для доступа, RT - для выдачи JWT.
Больше мне в голову ничего не лезет, может, я что-то очевидно пропускаю?
Дополнительно:
Живут токены 30 минут и 15 дней соответственно.
Не многовато?..
В SPA в пределах одной страницы это реализуется примерно так:
|
1 |
var isRefreshing = null; var refreshingCall = null; async function request() { while (true) { if (isRefreshing) { const refreshed = await refreshingCall; isRefreshing = false; } const response = await fetch(...); const data = await response.json(); if (!data.needRefresh) { return data; } isRefreshing = true; refreshingCall = doRefresh(...); } } async function doRefresh(...) { ... } |
Основная идея - использование глобального флага обновления токена и глобальной переменной с промисом. Первый запрос, обнаруживший необходимость обновления, выставляет флаг и записывает промис, который возвращает функция обновления. Второй (и последующие) запрос видит, что флаг уже стоит и просто ждёт выполнения промиса.
- Примерно такое же решение с флагами и предполагал, правда мне почему-то казалось, что есть какое-то оптимальное решение сугубо с серверной стороны, чтобы вообще не мучаться на клиенте. Что-то из разряда амортизирующих RT-токенов и такого подхода. Благодарю за ответ 🙂
Для решения данной проблемы вы можете воспользоваться услугами фрилансеров. Мы выполним необходимую работу быстро и качественно.
Оставить комментарий Отменить
Ответы
- Есть ответ! к записи Как уменьшить масштаб меньше 100% в Windows 10 (22H2)
- Есть ответ! к записи Аналоги CloudFlare в России?
- Есть ответ! к записи Аналоги CloudFlare в России?
- Есть ответ! к записи Как называется человек, который дизайн придумает для сайта и сверстает его?
- Есть ответ! к записи Можно ли установить Яндекс.Диск на АльтЛинукс?
- Есть ответ! к записи Картинки мутные только на сафари, есть выход?
- Есть ответ! к записи Keenetic. Как настроить SSTP клиент с сертификатом?
- Есть ответ! к записи Чем заменить executor в aiogram 3?
Для обновления пар JWT (JSON Web Token) и RT (Refresh Token) в API для нескольких клиентов, необходимо следовать определенным шагам и использовать bewährte Verfahren für die Implementierung.
1. **Хранение токенов**: Важно правильно хранить и управлять токенами для каждого клиента. Рекомендуется использовать безопасное хранилище, такое как база данных или кэширование, чтобы обеспечить безопасность и доступность токенов.
2. **Авторизация и аутентификация**: При обновлении токенов необходимо удостовериться, что клиент имеет право на обновление своих токенов. Для этого можно использовать механизм аутентификации, например, проверку идентификатора клиента и его секретного ключа.
3. **Механизм обновления**: Для обновления токенов можно использовать специальный эндпоинт в вашем API, который будет принимать текущий пар JWT и RT и выдавать новую пару токенов. Рекомендуется использовать HTTPS для защиты передачи данных.
Пример кода на PHP для обновления токенов:
4. **Обновление токенов на клиентской стороне**: После получения новой пары токенов на стороне сервера, необходимо обновить их на клиентской стороне. Это можно сделать путем замены старых токенов новыми в хранилище клиента или в куках.
Следуя этим рекомендациям и правильно реализуя обновление пар JWT и RT в вашем API, вы сможете обеспечить безопасность и надежность работы с токенами для нескольких клиентов.