Amazon web services 手动对要在Lambda中使用的AppSync URL进行签名出现错误

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

在Lambda中,我想用
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中有互联网:'(