当用户不一定经过身份验证时,如何拥有根级别 AppSync/Apollo 客户端?

How can I have a root level AppSync/Apollo client when the user isn't necessarily authenticated?

作为背景,我使用了 react、redux、react-router(v4)、react-cognito 和 appsync。我的应用程序使用 PrivateRoute 来确保用户对请求的每个路由都有授权。 react-cognito 为我处理所有身份验证并在 redux 存储中存储 JWT 令牌、联合身份临时 IAM 访问密钥/秘密访问密钥/会话令牌。

AppSync 教程假定您使用的是 AWS-amplify 而不是 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 public 不需要身份验证)而且我不确定可以调用什么异步函数在 mount 上拉这个一旦可用,就像在上面的例子中所做的那样。

目前我已经通过将 ApolloProvider 放在组件级别来解决这个问题,仅适用于需要它并且存在于 PrivateRoutes 中的组件(因此将在商店中提供凭据信息),但这会导致代码重复,感觉不对。

没有迁移到 aws-amplify,有什么关于如何重构它的建议吗?

您可以在根组件级别继续使用 ApolloProvider。仅在向 AppSync 发出请求之前需要时才会读取身份验证配置 API.

更多细节:

您传递给 AWSAppSyncClient 构造函数的配置中 auth 键下的对象可以包含不同的值,具体取决于您的 API 使用的身份验证类型。

  • apiKey 对于 API_KEY
  • credentials 对于 AWS_IAM
  • jwtToken 对于 AMAZON_COGNITO_USER_POOLS

这三个键可以包含值 或 return 承诺 将用值解析的函数。 AWSAppSyncClient 将在每个请求.

上获取值(或等待承诺)

在实例化时信息是否还没有在 redux-store 中并不重要。我没有测试过这个(另外,我不熟悉 react-cognito),但它会是这样的:

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
});