Manually sign AppSync URL to use in Lambda gives bad signature error

后端 未结 3 753
别那么骄傲
别那么骄傲 2021-01-03 13:48

In a Lambda, I would like to sign my AppSync endpoint with aws-signature-v4 in order to use it for a mutation.

The URL generated se

相关标签:
3条回答
  • 2021-01-03 14:16

    This is how I trigger an AppSync mutation using by making a simple HTTP-request, using axios.

    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
        });
    }
    

    Make sure to give the IAM-role your Lambda function is running as, permissions for appsync:GraphQL.

    0 讨论(0)
  • 2021-01-03 14:20

    Adding an answer here because I had difficulty getting the accepted answer to work and I found an issue on the AWS SDK GitHub issues that said it's not recommended to use the AWS.Signers.V4 object in production. This is how I got it to work using the popular aws4 npm module that is recommended later on in the issue linked above.

    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))
    
    0 讨论(0)
  • 2021-01-03 14:22

    You don't need to construct a pre-signed URL to call an AWS AppSync endpoint. Set the authentication mode on the AppSync endpoint to AWS_IAM, grant permissions to your Lambda execution role, and then follow the steps in the "Building a JavaScript Client" tutorial to invoke a mutation or query.

    0 讨论(0)
提交回复
热议问题