Как я могу получить клиент AppSync / Apollo корневого уровня, если пользователь не обязательно аутентифицирован?

В качестве фона я использую react, redux, response-router (v4), react -ognito и appsync. В моем приложении используется PrivateRoute, чтобы пользователь имел авторизацию для каждого запрошенного маршрута. response -ognito обрабатывает всю аутентификацию за меня и сохраняет токены JWT, временный ключ доступа IAM / секретный ключ доступа / токен сеанса в хранилище redux.

В руководстве по AppSync предполагается, что вы используете AWS-ampify вместо react-cognito, и помещает <ApolloProvider client = {this.client}> на уровне корневого приложения, где

this.client = new AWSAppSyncClient({
      url: AppSync.graphqlEndpoint,
      region: AppSync.region,
      auth: {

        // Amazon Cognito Federated Identities using AWS Amplify
        //credentials: () => Auth.currentCredentials(),

        // Amazon Cognito user pools using AWS Amplify
        // type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
        // jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken(),
      },
      disableOffline: true
    });
  }

В моем случае при монтировании корневого компонента в магазине пока нет ничего из react-cognito (половина моего SPA является общедоступной, не требующей аутентификации), и я не уверен, какая функция async может быть вызвана при монтировании, чтобы вытащить ее, когда она станет доступной, как кажется это необходимо сделать в приведенном выше примере.

На данный момент я решил эту проблему, разместив ApolloProvider на уровне компонентов, только для тех компонентов, которые в нем нуждаются и которые существуют в PrivateRoutes (следовательно, информация об учетных данных будет доступна в магазине), но это приводит к дублированию кода и кажется неправильным.

Если не считать перехода на aws-ampify, есть какие-нибудь предложения по его рефакторингу?


person davegravy    schedule 24.04.2018    source источник


Ответы (1)


Вы можете продолжать использовать ApolloProvider на уровне корневого компонента. Конфигурация аутентификации будет прочитана только при необходимости перед отправкой запроса в API AppSync.

Еще немного подробностей:

Объект под ключом auth в конфигурации, которую вы передаете конструктору AWSAppSyncClient, может содержать разные значения в зависимости от типа аутентификации, используемого вашим API.

  • apiKey для API_KEY
  • credentials для AWS_IAM
  • jwtToken для AMAZON_COGNITO_USER_POOLS

Эти три ключа могут содержать значения или функции, возвращающие обещание, которое будет разрешено вместе со значением. AWSAppSyncClient будет получать значение (или ожидать обещания) при каждом запросе.

Не имеет значения, если во время создания экземпляра информации еще нет в redux-store. Я не тестировал это (также я не знаком с react -ognito), но это будет примерно так:

this.client = new AWSAppSyncClient({
    url: AppSync.graphqlEndpoint,
    region: AppSync.region,
    auth: {
        type: AUTH_TYPE.AWS_IAM,
        credentials: async () => {
            const state = store.getState();

            return state.cognito.creds;
        }
    },
    disableOffline: true
});
person Manuel Iglesias    schedule 24.04.2018