【问题标题】:How to send signed HTTP request from AWS Lambda to AppSync GraphQL?如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?
【发布时间】:2019-11-19 00:34:43
【问题描述】:

我不确定如何在 AppSync GraphQL 端点上发送签名的 http 请求。 AWS 中没有用于执行此操作的库。

  • aws-amplify 不起作用,因为仅适用于浏览器,不适用于 Lambda 函数。
  • aws-sdk AppSync 仅供管理员使用,没有调用用户端api的方法

可以从 AWS Lambda 发出 IAM 签名的 HTTP 请求吗? (以某种简单的方式)

【问题讨论】:

    标签: javascript amazon-web-services aws-lambda graphql aws-appsync


    【解决方案1】:

    我会推荐阅读这篇文章:Backend GraphQL: How to trigger an AWS AppSync mutation from AWS Lambda,

    引用作者https://stackoverflow.com/users/1313441/adrian-hall,我们已经:

    GraphQL 通过 HTTPS 进行路由。这意味着我们可以使用简单的 HTTPS POST 来模拟 GraphQL 客户端库。由于我们使用的是 IAM,因此我们需要在交付请求之前对其进行签名。这是我的代码:

    // ... more code here
        // POST the GraphQL mutation to AWS AppSync using a signed connection
        const uri = URL.parse(env.GRAPHQL_API);
        const httpRequest = new AWS.HttpRequest(uri.href, env.REGION);
        httpRequest.headers.host = uri.host;
        httpRequest.headers['Content-Type'] = 'application/json';
        httpRequest.method = 'POST';
        httpRequest.body = JSON.stringify(post_body);
    
        AWS.config.credentials.get(err => {
            const signer = new AWS.Signers.V4(httpRequest, "appsync", true);
            signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
    
            const options = {
                method: httpRequest.method,
                body: httpRequest.body,
                headers: httpRequest.headers
            };
    
            fetch(uri.href, options)
    // ... more code here
    

    我一直将它用作我所有 Lambda->AppSync 通信的模板!

    【解决方案2】:

    您可以使用任何 graphql 客户端或 sigv4 签名的 HTTP 请求。以下是您为请求创建签名的方法 (https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)。如果您将执行角色附加到您的 lambda,您可以从 lambda 环境变量 (https://docs.aws.amazon.com/lambda/latest/dg/lambda-environment-variables.html) 访问它的访问密钥。

    【讨论】:

      【解决方案3】:

      这个问题已经回答了,但是因为我首先提出了这个问题,所以我想我会分享另一个解决方案。

      我的用例是向 AWS 上托管的自定义 HTTP API 发送签名请求,其中 cognito 用作身份验证后端,仅启用了 ALLOW_USER_SRP_AUTH(因此没有 ALLOW_ADMIN_USER_PASSWORD_AUTH 或 ALLOW_USER_PASSWORD_AUTH)

      我最终结合了 AWS 中的这个示例,展示了如何在节点中进行 cognito 身份验证:

      AWS 的另一个例子展示了如何签署请求:

      您通过替换这一行(来自第一个示例)将第二个示例插入到第一个示例中:

      //(...)
              //refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity()
              AWS.config.credentials.refresh(error => {
                  if (error) {
                      console.error(error);
                  } else {
                      // Instantiate aws sdk service objects now that the credentials have been updated.
                      // example: var s3 = new AWS.S3();
                      console.log('Successfully logged!'); // <-- replace this line
                  }
              });
      //(...)
      

      第二个示例需要进行一些调整以满足您的要求,我必须更改的是:

      • HTTP 方法(我需要 GET)
      • signer 声明 - 我不得不更改服务(将 es 替换为 execute-api
      • signer.addAuthorization 中,我不得不使用AWS.config.credentials(已经由第一个示例中的代码初始化)而不是AWS.EnvironmentCredentials('AWS')

      希望这对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 2020-04-15
        • 1970-01-01
        • 2020-09-10
        • 2022-01-12
        • 2021-11-02
        • 2023-03-30
        • 2019-09-30
        • 1970-01-01
        • 2020-06-03
        相关资源
        最近更新 更多