Hey guys, so I am making a Facebook messenger bot using the serverless framework (aws lambda). I would like to verify that the requests are coming from Facebook. Luckily, Facebook sends a hash of the request body with each request which I can use to verify, however, the hash they send along is a hash of the raw request body. I need to access the raw request body in order to generate my own hash and see if they match. Does anybody know how I can get that raw request? Thanks. Happy to provide more details if necessary.
If you’re using Lambda Proxy integration (the default) then you can use event.body
to access it.
Ok I see @buggy thanks. For some reason, sometimes the hashes match and other times they do not depending on what sort of data is in the request. Would you have any idea why that is? Here is my code for hash matching:
if (event['headers']['X-Hub-Signature']) {
var sha = event['headers']['X-Hub-Signature']
var body = event.body
return sha == `sha1=${crypto.createHmac('sha1', config.APP_SECRET).update(body).digest('hex')}`;
}
I’m having the same issue.
In my case the problem is that Lambda receives the body object already parsed.
If the origin system signed the json object with “{“number”: 1.0}”, the object received would be {number: 1}. This is because Javascript converts 1.0 to 1 during the JSON parse.
I couldn’t figure out yet how to solve this.
I was able to solve the problem by using Serverless templates.
The documentation at this point is not very clear, but you can basically overwrite how the request is parsed to your function.
There is a good AWS documentation here.
That’s how I solved it, trying to be as compatible as possible with default request event. I hope it helps someone.
PS. It seems to not work on Serverless Offline plugin.
request:
template:
application/json: |
{
"body": "$util.escapeJavaScript($input.json('$'))",
"rawbody": "$util.escapeJavaScript($input.body)",
"headers": {
#foreach($header in $input.params().header.keySet())
"$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end
#end
},
"query": {
#foreach($query in $input.params().querystring.keySet())
"$query": "$util.escapeJavaScript($input.params().querystring.get($query))" #if($foreach.hasNext),#end
#end
}
}