3

On Cloud Code on Parse Im trying to verify the header x-hub-signature received from Facebook webhook.

secret is the right secret-key of the Facebook app.

var
hmac,
expectedSignature,
payload = JSON.stringify(req.body),
secret = 'xyzxyzxyz';

hmac = crypto.createHmac('sha1', secret);
hmac.update(payload, 'utf-8');
expectedSignature = 'sha1=' + hmac.digest('hex');
console.log(expectedSignature);
console.log(req.headers['x-hub-signature']);

but the signatures never match. What is wrong?

GPack
  • 2,494
  • 4
  • 19
  • 50
  • What’s the actual contant of `payload`, after you used JSON.stringify? – CBroe Jun 21 '16 at 15:12
  • the string representation of the JSON received in the body, starting with {"entry":[{"changes":[....... – GPack Jun 21 '16 at 15:17

2 Answers2

6

Your bodyParserJSON should return rawBody:

bodyParser.json({
    verify(req, res, buf) {
      req.rawBody = buf;
    },
})

Here is a middleware that I've written. It uses crypto module to generate sha1

fbWebhookAuth: (req, res, next) => {
    const hmac = crypto.createHmac('sha1', process.env.FB_APP_SECRET);
    // hmac.update(req.rawBody, 'utf-8'); //older versions
    hmac.update(req.rawBody, 'utf8');
    if (req.headers['x-hub-signature'] === `sha1=${hmac.digest('hex')}`) next();
    else res.status(400).send('Invalid signature');
}

and finally in your route you can use it as:

app.post('/webhook/facebook', middlewares.fbWebhookAuth, facebook.webhook);
Salitha
  • 1,022
  • 1
  • 12
  • 32
Gijo Varghese
  • 11,264
  • 22
  • 73
  • 122
1

If you're parsing the body into an object with middleware, check out Node.js - get raw request body using Express

If you're already using the raw parsing module, it should work if you don't JSON.stringify req.body:

payload = req.body,
Community
  • 1
  • 1
David
  • 127
  • 1
  • 6