прослойки. Фронт авторизуется через BFF и держит авторизацию через сессию (express-session + connect-redis). JWT токен хранится на стороне BFF в сессии. Кроме access токена хранится ещё refresh token. И вот проблема в реализации нормального рефреша. Пользователь открывает страницу, сразу отправляется пачка параллельных запросов за всякими данными, словарями и прочим. Я в guard'е проверяю не истёк ли токен, и если истёк, то отправляю запрос на refresh и обновляю в сессии access token. Но когда запросов много одновременно, то в итоге формируется целая пачка access токенов. Пытался синхронизировать через redis. Типа записывать в сессию флаг о том, что выполняется рефреш токена. В созданный для этого канал пушится сообщение о начале рефреша. При этом подписанные к этому каналу на это событие подгружают актуальную сессию через req.session.reload(). Но это не работает, всё равно успевают создаться несколько сессий.
Собственно вопрос какие есть способы добиться, чтобы в один момент времени какое-то событие произошло только один раз при нескольких параллельных запросах в, например, 2 одновременно запущенных подах с NestJS? Были мысли сделать это через очередь. Но боюсь, что проблема будет той же - запросы на рефреш отправятся раньше, чем станет известно, что параллельно он уже выполняется.
Кажется, что проблему надо решать на фронте. Так как пачка одинаковых запросов - это неправильно
Запросы то разные, просто отправляются одновременно при загрузке страницы.
Запросы всяких списков, справочников типа /currencies, /countries, /some-list
Касательно того, как сделать так, чтобы только один запрос уходил на запрос токена, а остальные ждали, то можешь посмотреть как работают pool'ы конекшенов, например тут. Если я правильно понял, то проблема похожа
Да, похоже, но здесь сработает, если нода запущена одна. А у нас запускается параллельно два пода с приложением. С таким вариантом просто отправится не более 2 запросов. Что уже лучше, конечно. Но не полностью решит ситуацию.
Тогда если нужен один access на все иснтансы, то пусть инстаны ноды лезут в общее хранилище (например redis) и получаю токен оттуда. А в редис его будет класть другой бекграунд процесс раз в N времени
Он и лежит в redis - в сессии
Пусть его кладёт один бекграунд процесс раз в N времени. А не так, что каждый инстанс пытался бы договориться с другими, кто же его туда положит
Да я вот уже думаю о том, чтобы просто автоматически рефрешить эти токены по крону... Это будет примерно тоже самое, тоже обновляться раз в N времени.
Я думаю мы тогда говорим об одном и том же
А почему не работает синк через редис? При правильной реализации редлока у тебя только один процесс сможет "захватить флаг", и он же будет обновлять токен, и рассылать его Почему это не работает и создаются несколько сессий?
Обновлять токены для пользователей без активного соединения? Это звучит странно
Ну токен создаётся не на стороне этого BFF, а в другом микросервисе, отвечающем за пользователей и авторизацию. На каждый запрос рефреша создаётся новый токен. В редис в сессии то лежит всего один. А вот в базе микросервиса уже их несколько.
Обсуждают сегодня