JWT обновлялся не полностью после миграции сервиса

Симптом

После переноса старого сервиса на отдельный домен и базу данных пользователи начали периодически вылетать из системы.

Контекст

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

Корневая причина

Во frontend-логике обновления токенов заменялся access_token, но не refresh_token. Следующий цикл обновления использовал старый refresh token и завершался неуспешно.

Проблему усиливали две ошибки конфигурации: имена переменных в CI не совпадали с именами, которые читал backend, а отсутствующее значение незаметно заменялось коротким значением по умолчанию для refresh token. В результате поведение зависело от окружения и проявлялось как случайный logout.

Ошибочное предположение

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

Обнаружение

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

Исправление

Мы исправили frontend-обработку так, чтобы при обновлении сохранялись оба токена, и убрали значения по умолчанию для обязательных JWT-переменных окружения. Несовпадение имён переменных в CI и backend также было устранено.

Теперь отсутствие ключевой настройки должно проявляться при запуске сервиса, а не через случайные logout пользователей спустя некоторое время.

Проверка

Регрессионная проверка должна:

  1. выдать пару токенов;
  2. выполнить обновление после истечения access token;
  3. убедиться, что клиент сохранил новый access_token и новый refresh_token;
  4. повторить обновление с новой парой.

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

Общий вывод

Секреты и параметры безопасности не должны иметь тихих значений по умолчанию. Контракт обновления токенов нужно проверять как единый протокол: клиент должен сохранить все обновлённые значения, backend - выдать согласованную пару, а CI - передать именно те переменные, которые использует приложение.