首页 > 解决方案 > 如何使用 Cognito 身份池和 Amplify 连接到 AWS AppSync

问题描述

我有一个使用 IAM 角色进行身份验证的 AWS AppSync API。我正在使用 Amplify GraphQL 客户端连接到 AppSync 服务器。下图描述了获取 IAM 凭证所需执行的步骤,我假设 Amplify 能够执行这些步骤。但是,我找不到任何有关如何设置工作示例的文档。

请注意,我直接使用 Cognito 用户池进行身份验证,而不是像 Google 或 Facebook 这样的外部提供商。

使用用户池和身份池访问 AWS 服务

到目前为止,我能够对用户进行身份验证并获得 JWT 令牌(步骤 1):

const Amplify = require('aws-amplify').default
const { Auth } = require('aws-amplify')


Amplify.configure({
  Auth: {
    region: process.env.AWS_REGION,
    userPoolId: process.env.COGNITO_USERPOOL_ID,
    userPoolWebClientId: process.env.COGNITO_WEBCLIENT_ID,
  },
})

Auth.signin(username, password)
  .then((user) => {
    const token = user.idToken.jwtToken
    // I've got the token - what next?
  })

如何从身份池请求 IAM 凭证(步骤 2),并使用它们通过 Amplify 访问 AppSync API(步骤 3)?

如果 Amplify 本身无法获取凭证,我可以使用AWS.CognitoIdentityCredentialsAWS 开发工具包来请求它们,但是,我看不到将它们传递给 Amplify 以验证 API 请求的方法(请参阅为更多细节)。

标签: javascriptamazon-web-servicesauthenticationaws-appsyncaws-amplify

解决方案


我能够使用 cognito 对我的客户端进行身份验证,然后将 jwtToken 传递给 aws-appsync 客户端,以便能够将 APPSYNC 与 AMAZON_COGINITO_USER_POOLS 一起使用。同样在代码中,您将看到我在哪里使用 API_KEY 作为替代方案。我将 API_KEY 注释掉了。对于那些也想尝试使用 Apollo 客户端和 aws-appsync 访问的人,我将其作为替代方案分享。

if (!process.browser) {
  global.fetch = require('node-fetch')
}

const appSyncClientOptions = {
  url: awsConfig.aws_appsync_graphqlEndpoint, 
  region: awsConfig.aws_appsync_region,
  auth: {
    // type: 'API_KEY',
    // apiKey: awsConfig.aws_appsync_apiKey,
    type: awsConfig.aws_appsync_authenticationType,   // 'AMAZON_COGNITO_USER_POOLS'
    jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken()
  },
  disableOffline: true,
};

const apolloClientOptions = {
  link: createAppSyncLink({
    ...appSyncClientOptions,
    resultsFetcherLink: createHttpLink({ uri: appSyncClientOptions.url, fetch })
  })  
};

const client = new Client(appSyncClientOptions, apolloClientOptions);

const WithProvider = () => (
  <ApolloProvider client={client}>
    <Rehydrated>
      <GqlList />
    </Rehydrated>
  </ApolloProvider>
)

export default WithProvider;

推荐阅读