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')}`;
}
Hey @badboy did you manage to work this out? Any ideas why it wasn’t working for you?
Cheers
Liam
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
}
}
@williamgurzoni hey did you or anyone else find any way to do it with serveless offline.