首页 > 解决方案 > 当用户不一定经过身份验证时,如何拥有根级别的 AppSync/Apollo 客户端?

问题描述

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

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 是公开的,不需要身份验证),我不确定在安装时可以调用什么异步函数来拉取这个似乎可用在上面的例子中完成。

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

没有迁移到 aws-amplify,有什么建议可以重构它吗?

标签: reactjsreduxamazon-cognitoaws-cognitoaws-appsync

解决方案


您可以继续ApolloProvider在根组件级别使用 。在向 AppSync API 发出请求之前,只有在需要时才会读取 auth 配置。

更多细节:

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

  • apiKey为了API_KEY
  • credentials为了AWS_IAM
  • jwtToken为了AMAZON_COGNITO_USER_POOLS

这三个键可以包含返回将使用该值解析的承诺的值或函数。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
});

推荐阅读