如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?
Posted
技术标签:
【中文标题】如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?【英文标题】:How to send signed HTTP request from AWS Lambda to AppSync GraphQL? 【发布时间】:2019-11-19 00:34:43 【问题描述】:我不确定如何在 AppSync GraphQL 端点上发送签名的 http 请求。 AWS 中没有用于执行此操作的库。
aws-amplify
不起作用,因为仅适用于浏览器,不适用于 Lambda 函数。
aws-sdk
AppSync 仅供管理员使用,没有调用用户端api的方法
可以从 AWS Lambda 发出 IAM 签名的 HTTP 请求吗? (以某种简单的方式)
【问题讨论】:
【参考方案1】:我会推荐阅读这篇文章:Backend GraphQL: How to trigger an AWS AppSync mutation from AWS Lambda,
引用作者https://***.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 通信的模板!
【讨论】:
更新链接Backend GraphQL: How to trigger an AWS AppSync mutation from AWS Lambda【参考方案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 身份验证:
https://www.npmjs.com/package/amazon-cognito-identity-js(用例 4)AWS 的另一个例子展示了如何签署请求:
https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-request-signing.html#es-request-signing-node您通过替换这一行(来自第一个示例)将第二个示例插入到第一个示例中:
//(...)
//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')
希望这对某人有所帮助!
【讨论】:
以上是关于如何将签名的 HTTP 请求从 AWS Lambda 发送到 AppSync GraphQL?的主要内容,如果未能解决你的问题,请参考以下文章
AWS S3 通过预签名 URL 上传返回 400 错误请求
AWS S3 - 我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法
从 .Net 应用程序到 AWS API Gateway 的 HTTP POST 请求未按预期工作