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

Как разработчики мы не знаем, когда истечет этот срок, так как для этого есть много причин, и в целом наше клиентское приложение старается не замечать технических деталей на стороне сервера. Итак, в любом из наших запросов нам нужно иметь возможность обрабатывать сценарий с истекшим токеном доступа.

Процесс повторной аутентификации для запросов

Сначала запрос отклоняется с сообщением об ошибке. Затем мы используем токен обновления для получения нового токена доступа, и, наконец, запрос повторяется с новым токеном доступа. Apollo будет обрабатывать фактические запросы к серверу за нас. Однако для реализации процесса повторной аутентификации нам потребуется продлить этот процесс создания запроса.

Использование Apollo Client 2.0 «Links» для расширения сетевого интерфейса

Метод расширения сетевого интерфейса клиента Apollo заключается в том, что они называют ссылками. Обзор Apollo Link (Официальная документация).

Ссылки позволяют нам создавать набор функций, которые могут взаимодействовать и манипулировать нашим запросом до их выполнения.

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

Конечная ссылка по умолчанию, которую предоставляет Apollo, - apollo-http-link. Эта завершающая ссылка выполняет сетевой запрос с использованием fetch и отправляет обратно результат. Вы можете создать ссылку, используя функцию createHttpLink() из пакета apollo-http-link. В приведенном выше примере мы передаем URI для сервера graphql, чтобы он знал, куда отправить запрос, а также заголовки, необходимые для аутентификации.

Реализация процесса повторной авторизации

Чтобы реализовать поток повторной авторизации, указанный выше, мы можем переопределить fetch, выполняемый завершающей ссылкой. Мы создаем customFetch функцию, которая может выполнить запрос и повторить попытку с новым токеном в случае сбоя, и передаем это в качестве опции apollo-http-link.

...
const httpLink = createHttpLink({
    uri: "/graphql",
    fetch: customFetch,
    headers: {...}
})
...

Вот реализация функции customFetch, которая будет добавлена ​​в Apollo-Client:

Теперь, когда запрос выполняется, мы проверяем наличие несанкционированной ошибки перед возвратом результатов. Если у пользователя есть токен доступа с истекшим сроком действия, ссылка получит новый с использованием токена обновления и попытается повторить запрос.

Если ошибок нет, мы возвращаем начальный ответ в цепочке и переходим к следующему. Обратите внимание, как мы передаем по цепочке и начальный ответ ( using .clone() ), и response.json() .

return ({
    initialResponse: response.clone(),
    json: response.json()
});

Причина вышеупомянутого трюка заключается в том, что вызов функции response.json () использует ответ, и после этого нам нужно переупаковать обещание и вернуть его в качестве окончательного результата. Итак, чтобы избежать переупаковки (которая может привести к непредвиденным результатам в каждом случае), мы можем просто клонировать первоначальный запрос и подготовить его, когда он нам понадобится. Имейте в виду, что fetch ожидает функцию, возвращающую Promise ‹Response›.

Вот и все. Надеюсь, эта реализация позволит вам беспрепятственно работать с пользователем без неожиданного выхода из системы.

Больше контента на plainenglish.io