Amazon web services 手动对要在Lambda中使用的AppSync URL进行签名出现错误
在Lambda中,我想用Amazon web services 手动对要在Lambda中使用的AppSync URL进行签名出现错误,amazon-web-services,aws-lambda,aws-appsync,Amazon Web Services,Aws Lambda,Aws Appsync,在Lambda中,我想用aws-signature-v4对我的AppSync端点进行签名,以便将其用于突变 生成的URL似乎正常,但在我尝试时,它会给我以下错误: { “错误”:[{ “errorType”:“InvalidSignatureException”, “消息”:“我们计算的请求签名与您提供的签名不匹配。请检查您的AWS秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。等等。。。 } ] } 这是我的lambda函数 从“aws lambda”导入{Context,Callba
aws-signature-v4
对我的AppSync
端点进行签名,以便将其用于突变
生成的URL似乎正常,但在我尝试时,它会给我以下错误:
{
“错误”:[{
“errorType”:“InvalidSignatureException”,
“消息”:“我们计算的请求签名与您提供的签名不匹配。请检查您的AWS秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。等等。。。
} ]
}
这是我的lambda函数
从“aws lambda”导入{Context,Callback};
从“graphql请求”导入{GraphQLClient};
const v4=require('aws-signature-v4');
导出异步函数句柄(事件:任意、上下文:上下文、回调:回调){
context.callbackhaitsforemptyeventloop=false;
常量url=v4.createPresignedURL(
"岗位",,
'xxxxxxxxxxxxxxxxx.appsync api.eu-west-1.amazonaws.com',
“/graphql”,
“appsync”,
“无符号有效载荷”,
{
键:“YYYYYYYYYYYYYY”,
秘密:“ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ”,
地区:“欧盟-西部-1”
}
);
常数突变=`{
FAKEviewProduct(标题:“初始阶段”){
产品ID
}
}`;
const client=new GraphQLClient(url{
标题:{
“内容类型”:“应用程序/graphql”,
操作:“GetDataSource”,
版本:2017-07-25
}
});
试一试{
等待client.request(突变,{productId:'jfsjfksldjfsdkjfsl'});
}捕捉(错误){
控制台日志(err);
回调(Error());
}
回调(null,{});
}
通过创建一个新用户并允许他appsync:GraphQL
操作,我获得了我的key
和secret
我做错了什么?调用AWS AppSync终结点不需要构造预签名URL。将AppSync终结点上的身份验证模式设置为AWS_IAM,将权限授予您的,然后按照教程中的步骤调用变异或查询。这是我使用使用axios
发出简单的HTTP请求
const AWS = require('aws-sdk');
const axios = require('axios');
exports.handler = async (event) => {
let result.data = await updateDb(event);
return result.data;
};
function updateDb({ owner, thingName, key }){
let req = new AWS.HttpRequest('https://xxxxxxxxxxx.appsync-api.eu-central-1.amazonaws.com/graphql', 'eu-central-1');
req.method = 'POST';
req.headers.host = 'xxxxxxxxxxx.appsync-api.eu-central-1.amazonaws.com';
req.headers['Content-Type'] = 'multipart/form-data';
req.body = JSON.stringify({
"query":"mutation ($input: UpdateUsersCamsInput!) { updateUsersCams(input: $input){ latestImage uid name } }",
"variables": {
"input": {
"uid": owner,
"name": thingName,
"latestImage": key
}
}
});
let signer = new AWS.Signers.V4(req, 'appsync', true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
return axios({
method: 'post',
url: 'https://xxxxxxxxxxx.appsync-api.eu-central-1.amazonaws.com/graphql',
data: req.body,
headers: req.headers
});
}
确保为Lambda函数运行时的IAM角色授予appsync:GraphQL
在此处添加答案的权限,因为我很难获得可接受的答案,并且我在上发现了一个问题,即不建议在生产中使用AWS.Signers.V4
对象。我就是这样做的使用流行的npm模块进行工作,该模块稍后将在上面链接的问题中推荐
const axios = require('axios');
const aws4 = require('aws4');
const query = `
query Query {
todos {
id,
title
}
}`
const sigOptions = {
method: 'POST',
host: 'xxxxxxxxxx.appsync-api.eu-west',
region: 'eu-west-1',
path: 'graphql',
body: JSON.stringify({
query
}),
service: 'appsync'
};
const creds = {
// AWS access tokens
}
axios({
url: 'https://xxxxxxxxxx.appsync-api.eu-west/graphql',
method: 'post',
headers: aws4.sign(sigOptions, creds).headers,
data: {
query
}
}).then(res => res.data))
我理解,但因为我只需要在我的lambdas环境中进行一次变异,我认为使用客户端会有点过火,而且相当繁重。使用签名HTTP请求应该更快、更轻,你不认为吗?只有在服务支持预签名URL的情况下,预签名URL才有效。据我所知,只有Amazon S3和AWS IoT支持预签名ed URL。AWS AppSync目前不支持预签名URL。如果您不想使用AppSync客户端,您可以使用任何其他HTTP客户端进行GraphQL调用。非常完美。非常感谢。您的评论解释了3天的错误和误解。谢谢。谢谢。看起来很棒!我会尽快尝试并让您确认现在。谢谢你的帮助!看起来是个不错的解决方案!我自己也尝试过了,我从我的lambda中得到了以下错误。不确定这里的问题是什么,也许你知道为什么会发生这种情况?我的lambda附加了awsapsyconinvokeellaccess
策略,它应该提供appsync:GraphQL
write-EPROTO 139686890170176:错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败:../deps/openssl/openssl/SSL/s23_clnt.c:802:
@Tom您尝试过这个解决方案吗?它对您有效吗?它对我有效。我只是从新的AWS.HttpRequest
参数中添加了https
。您的错误谈到了SSL,可能不是这就是问题所在。Thank mate工作起来很有魅力!就像你从aws-sdk中挑选东西一样。得到与@MånsDahlströM相同的错误。除了使用节点6(我不想这么做)之外,没有找到太多关于如何修复它的方法。嗨,Tom!结果如何?@Robbann它工作起来了!我必须在axios
调用中的url参数中添加https://
嗯。现在我很难将我的VPC配置为在我的lambda中有互联网:'(