Как правильно реализовать jwt-аутентификацию?
Пытаюсь разобраться с jwt-аутентификацией. Начитался статей и у меня возник вопрос. В большинстве туториулов, которые мне попадались, использовали отдельный обработчик запросов для "refresh_token". Что-то типа такого:
serverApp.post("/refresh-tokens", ...)
В таком случае получается, что когда время жизни "access_token" иссякнет, то сначала сервер вернет клиенту соответственную ошибку, после чего клиент должен обратиться к "/refresh-tokens", получить новые токены и вновь повторить запрос. Есть еще вариант. Здесь автор предлагает следующее:
- Клиент(фронтенд) проверяет перед запросом не истекло ли время жизни access token'на
- Если истекло клиент делает запрос на POST auth/refresh-tokens { fingerprint: string } в body и соответственно refreshToken куку.
- Сервер получает запись рефреш-сессии по UUID'у рефреш токена
- Сохраняет текущую рефреш-сессию в переменную и удаляет ее из таблицы
- Проверяет текущую рефреш-сессию:
5.1. Не истекло ли время жизни
5.2. На соответствие старого fingerprint'a полученного из текущей рефреш-сессии с новым полученным из тела запроса - В случае негативного результата бросает ошибку TOKEN_EXPIRED/INVALID_REFRESH_SESSION
- В случае успеха создает новую рефреш-сессию и записывает ее в БД Создает access token
- Отправляет клиенту access и refresh token uuid (взятый из выше созданной рефреш-сессии).
Внимание стоит обратить на первый пункт. То есть, чтобы не делать заведомо "неудачный" запрос, который вернет ошибку из-за иссякнувшего времени жизни "access_token", стоит на клиенте проверить нужно ли нам будет генерировать новую пару токенов.
Мой вопрос заключается в следующем. Зачем нам нужен отдельный запрос на "/refresh-tokens"? Почему, скажем, сразу же на первом запросе к серверу не сгенерировать пару токенов, если "access_token" не валиден по времени? Зачем нужна двойная работа? Даже если "/refresh-tokens" будет в виде отдельного сервиса, то зачем нам возвращаться к клиенту и от него делать запрос, если можно сделать это с сервера? Я в этих вопросах новичок, потому могу чего-то не понимать. Пожалуйста, помогите разобраться. Спасибо.