如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?

How to send signed HTTP request from AWS Lambda to AppSync GraphQL?

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

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

您可以使用任何 graphql 客户端或 sigv4 签名的 HTTP 请求。以下是您如何为您的请求创建签名 (https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). If you attach an execution role to your lambda you can access it access key from lambda environment variables (https://docs.aws.amazon.com/lambda/latest/dg/lambda-environment-variables.html)。

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

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

GraphQL is routed over HTTPS. That means we can simulate the GraphQL client libraries with a simple HTTPS POST. Since we are using IAM, we need to sign the request before we deliver it. Here is my code for this:

// ... 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 通信的模板!

这个问题已经得到解答,但由于它首先出现在我面前,所以我想我会分享另一个解决方案。

我的用例是向托管在 AWS 上的自定义 HTTP API 发送签名请求,其中 cognito 被用作只启用了 ALLOW_USER_SRP_AUTH 的身份验证后端(所以没有 ALLOW_ADMIN_USER_PASSWORD_AUTH也不 ALLOW_USER_PASSWORD_AUTH)

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

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')

希望这对某人有所帮助!