简体   繁体   English

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

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

I am not sure how to send signed http request do AppSync GraphQL endpoint.我不确定如何将签名的 http 请求发送到 AppSync GraphQL 端点。 There is no library for do that in AWS. AWS 中没有用于执行此操作的库。

  • aws-amplify don't work because works only in browser, not in Lambda function. aws-amplify不起作用,因为仅适用于浏览器,而不适用于 Lambda 函数。
  • aws-sdk for AppSync is only for admin usage, it doesn't have methods for call user side api AppSync 的aws-sdk仅供管理员使用,它没有调用用户端 api 的方法

It is possible to make IAM signed HTTP request from AWS Lambda?是否可以从 AWS Lambda 发出 IAM 签名的 HTTP 请求? (in some easy way) (以某种简单的方式)

i would recommend reading this article: Backend GraphQL: How to trigger an AWS AppSync mutation from AWS Lambda ,我建议阅读这篇文章: 后端 GraphQL:如何从 AWS Lambda 触发 AWS AppSync 突变

quoting the author, https://stackoverflow.com/users/1313441/adrian-hall , we've:引用作者https://stackoverflow.com/users/1313441/adrian-hall ,我们已经:

GraphQL is routed over HTTPS. GraphQL 通过 HTTPS 路由。 That means we can simulate the GraphQL client libraries with a simple HTTPS POST.这意味着我们可以使用简单的 HTTPS POST 模拟 GraphQL 客户端库。 Since we are using IAM, we need to sign the request before we deliver it.由于我们使用的是 IAM,因此我们需要在提交请求之前对其进行签名。 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

I've been using it as a template for all my Lambda->AppSync communication!我一直将它用作我所有 Lambda->AppSync 通信的模板!

You can use any graphql client or a sigv4 signed HTTP request.您可以使用任何 graphql 客户端或 sigv4 签名的 HTTP 请求。 Here's how you create the signature for your request ( https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html ).以下是为请求创建签名的方法 ( 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 ).如果您将执行角色附加到您的 lambda,您可以从 lambda 环境变量( https://docs.aws.amazon.com/lambda/latest/dg/lambda-environment-variables.html )访问它的访问密钥。

This question is already answered but since it came up first for me I thought I'd share another solution.这个问题已经得到了回答,但是因为它首先出现在我身上,所以我想我会分享另一个解决方案。

My use-case was to send a signed request to custom HTTP API hosted on AWS where cognito was used as authentication backend that only had ALLOW_USER_SRP_AUTH enabled (so no ALLOW_ADMIN_USER_PASSWORD_AUTH nor ALLOW_USER_PASSWORD_AUTH)我的用例是向 AWS 上托管的自定义 HTTP API 发送一个签名请求,其中 cognito 用作身份验证后端,仅启用了 ALLOW_USER_SRP_AUTH(因此没有 ALLOW_ADMIN_USER_PASSWORD_AUTH 也没有 ALLOW_USER_PASSWORD_AUTH)

I ended up combining this example from AWS showing how to do cognito authentication in node:我最终结合了来自 AWS 的这个示例,展示了如何在节点中进行认知身份验证:

With the other example from AWS showing how to sign request: AWS 的另一个示例显示了如何签署请求:

You plug in the second example into the first example by replacing this line (from first example):您可以通过替换此行(来自第一个示例)将第二个示例插入到第一个示例中:

//(...)
        //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
            }
        });
//(...)

Second example needs some tweaks to fit your requirements, things I had to change was:第二个示例需要进行一些调整以满足您的要求,我必须更改的内容是:

  • HTTP method (I needed GET) HTTP 方法(我需要 GET)
  • signer declaration - I had to change service (replaced es with execute-api ) signer声明 - 我必须更改服务(用execute-api替换es
  • In signer.addAuthorization I had to use AWS.config.credentials (already initialized by the code from first example) instead of AWS.EnvironmentCredentials('AWS')signer.addAuthorization我不得不使用AWS.config.credentials (已经由第一个示例中的代码初始化)而不是AWS.EnvironmentCredentials('AWS')

Hope this helps someone!希望这可以帮助某人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM