Остановить последующие запросы в apollo после возврата 401?

Я использую клиент apollo, чтобы сделать запрос в моем компоненте. Он состоит из 2 запросов. Как мне запретить ему отправлять другой запрос после того, как он дал мне ошибку 401? Я использую onError Apollo Link Error, чтобы отслеживать ошибки. Однако он отправляет оба запроса, и я не могу остановить следующий.


person Byrd    schedule 13.01.2018    source источник


Ответы (1)


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

Раньше я использовал что-то вроде следующего. В приведенном ниже примере специально обрабатывается аутентификация носителя с помощью токенов обновления, но тот же принцип можно использовать для обработки любого сбоя аутентификации.

import { ApolloLink, Observable } from 'apollo-link';

const isAuthError = (statusCode: number) => [401, 403].includes(statusCode);

const authLink = new ApolloLink((operation, forward) => {
  // Set outgoing Authorization headers
  const setHeaders = () =>
    operation.setContext(({ store, headers, ...rest }) => {
       // get the authentication token from local storage if it exists
       const token = localStorage.getItem('token');
       // return the headers to the context so httpLink can read them

      return {
        ...rest,
        store,
        headers: {
          ...headers,
          authorization: `Bearer ${token}`
        }
      };
    });

  setHeaders();

  return new Observable(obs => {
    const subscriber = {
      next: obs.next.bind(obs),
      // Handle auth errors. Only network or runtime errors appear here.
      error: error => {
        if (isAuthError(error.statusCode)) {
          // Trigger an auth refresh.
                refreshTokenOrLogin()
                  .then(setHeaders)
                  .then(() => forward(operation).subscribe(subscriber));
              }
            }
          });
        } else {
          obs.error(error);
        }
      },
      complete: obs.complete.bind(obs)
    };

    forward(operation).subscribe(subscriber);
  });
});

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

operation.setContext(({ store, headers, ...rest }) => {
   // get the authentication token from local storage if it exists
   const token = localStorage.getItem('token');
   // return the headers to the context so httpLink can read them

  return {
    ...rest,
    store,
    headers: {
      ...headers,
      authorization: `Bearer ${token}`
    }
  };
});

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

new Observable(obs => {
    const subscriber = {
      next: obs.next.bind(obs),
      // Handle auth errors. Only network or runtime errors appear here.
      error: error => {
        if (isAuthError(error.statusCode)) {
          // Trigger an auth refresh.
                refreshTokenOrLogin()
                  .then(setHeaders)
                  .then(() => 
                    // We can now retry the request following a successful token refresh.
                    forward(operation).subscribe(subscriber)
                  );
              }
            }
          });
        } else {
          obs.error(error);
        }
      },
      complete: obs.complete.bind(obs)
    };

    forward(operation).subscribe(subscriber);
  });

Было бы проще представить это как 2 ссылки. Один, который устанавливает исходящий контекст аутентификации, а другой, который фиксирует ответ и обрабатывает ошибки аутентификации.

person imranolas    schedule 14.01.2018