mreinstein / alexa-verifier

✓ Verify HTTP requests sent to an Alexa skill are sent from Amazon
MIT License
76 stars 23 forks source link

for valid signed requests its responding false. #62

Closed mehdi89 closed 5 years ago

mehdi89 commented 5 years ago

Hello,

Thank you for the solution, but it's not working for me. it's failing to verify the signature for 2nd, 3rd call from Alexa and passing all other functional tests calls from lambda. But when I run it's separately with the same signature, chainURL and raw body it's working. I can't get around my head into this issue. why it will work separately but not working from the server for 2nd, 3rd call. I know its not an actual issue, but any kind of help will be very much appreciated.

Thank you in advance.

mreinstein commented 5 years ago

Are you running express for the server on your backend?

mehdi89 commented 5 years ago

No, we deployed this as lambda function. its using https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

mreinstein commented 5 years ago

If you deployed this as a lambda function, this module is unnecessary. Read: https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html

You do not need to verify that requests are coming from the Alexa service yourself. Access to execute your function is controlled by permissions within AWS instead.

mehdi89 commented 5 years ago

No, we actually not using the integrated lambda function. We are using endpoints. just the endpoint is deployed in lambda. we are using API Gateway with lambda.

So, it's like other web service endpoint just its deployed in lambda.

mreinstein commented 5 years ago

What does your code look like around the place which takes the request headers and calls verifier() ?

mehdi89 commented 5 years ago
exports.handler = function (event, context, callback) {
    var cert_url = event.headers.SignatureCertChainUrl;
    var signature = event.headers.Signature;

    var body = JSON.parse(event.body);

    verifier(cert_url, signature, JSON.stringify(body)).then(() => {
        //signature verified 

    }).catch((err) => {
        console.log('cert_url', cert_url);
        console.log('signature', signature);
        console.log('body', JSON.stringify(body));
        console.log('errormessage', err);
        console.log("-----------------------------------");
        var response = {
            status: 400,
            errors: [{
                code: "234",
                source: "certificate",
                message: err,
                detail: err
            }]
        }
        context.fail(JSON.stringify(response));
    });
}

here it is.

mreinstein commented 5 years ago

@mehdi89 sorry for the reply delay, was @ brunch.

You're taking the raw request body and parsing it as JSON, then stringifying it again.

event.body !== JSON.stringify(JSON.parse(event.body))

This is probably what you want:

verifier(cert_url, signature, event.body).then(() => {
...

By the way you're like the 5th person that has been burned by this requirement. If you think of a way to word usage more clearly in the README, I'd really appreciate a pull request (PR) to update the documentation.

mehdi89 commented 5 years ago

I will try this tomorrow if it works. will definitely help to clarify this with a pull request. Thank you so much for taking the time. I really appreciate your help.

mreinstein commented 5 years ago

my pleasure, good luck!

mehdi89 commented 5 years ago

At last, we moved our solution from lambda to Elastic Beanstalk and used alexa-verifier-middleware with express. I didn't yet able to try that in the lambda deployment to confirm if this works or not.