Skip to content

Instantly share code, notes, and snippets.

@shawncarr
Last active May 25, 2017 12:07
Show Gist options
  • Select an option

  • Save shawncarr/9513545 to your computer and use it in GitHub Desktop.

Select an option

Save shawncarr/9513545 to your computer and use it in GitHub Desktop.
Validating a Mandrill Webhook request for nodejs
var Crypto = require('crypto');
/**
* validates a mandrill webhook request
* @param url string the url that mandrill sent the request to
* @param key string the web hook key from https://mandrillapp.com/settings/webhooks
* @param params array the request's POST parameters i.e. req.params
* @param compareTo string the x-mandrill-signature header value
*/
var validate = function validate(url, key, params, compareTo) {
var data = url;
for(var postKey in params) {
data += postKey;
data += postData[postKey];
}
var signer = Crypto.createHmac('sha1', key);
var signature = signer.update(data).digest('base64');
return compareTo && signature === compareTo;
};
@nuarhu

nuarhu commented Dec 4, 2014

Copy link
Copy Markdown

You might need to escape the forward slashes in the body. At least the string used by Mandrill as body will have escaped forward slashes.

@gregbarcza

Copy link
Copy Markdown

postData should be params at line 14

@diorahman

Copy link
Copy Markdown

In express + body-parser:

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const server = express();

server.use(bodyParser.urlencoded({extended: true}));

const key = 'your_random_webhook_key';
let url = 'http://your-webhook.com?handler=hello';

server.post('/hook', (req, res) => {
    let keys = Object.body.keys().sort();
    for (let key of keys) {
        url += key + req.body[key];
    }
    let signer = crypto.createHmac('sha1', key);
    let signature = signer.update(url).digest('base64');
    console.log(req.headers['x-mandrill-signature'] === signature);
    res.send(req.headers['x-mandrill-signature'] === signature ? 'Yeay!' : 'Nay!');
});

server.listen(8000 || env.process.PORT);

@teckays

teckays commented Feb 13, 2017

Copy link
Copy Markdown

One line alternative to this:

let keys = Object.body.keys().sort(); // which should actually be Object.keys(body).sort()
for (let key of keys) {
    url += key + req.body[key];
}

url += Object.keys(body).sort().map(key => ${key}${body[key]})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment