我正在开发一个Node.js应用程序,我正在努力验证Mandrill Webhook请求。
如前所述http://help.mandrill.com/entries/23704122-Authenticating-webhook-requests在PHP中它应该是这样的:
/**
* Generates a base64-encoded signature for a Mandrill webhook request.
* @param string $webhook_key the webhook's authentication key
* @param string $url the webhook url
* @param array $params the request's POST parameters
*/
function generateSignature($webhook_key, $url, $params) {
$signed_data = $url;
ksort($params);
foreach ($params as $key => $value) {
$signed_data .= $key;
$signed_data .= $value;
}
return base64_encode(hash_hmac('sha1', $signed_data, $webhook_key, true));
}
所以我想出了这个:
var url = "http://....";
var post = "<POST Data>";
require('crypto').createHmac("SHA1", "<Webhook Signature Key>").update(url+post).digest("base64");
不幸的是,这不起作用。我得到了不同的签名。
POST数据来自urlencoded,例如:
mandrill_events=%5B%7B%22event%22%3A%22inbound ...
Urldecoded:
mandrill_events=[{"event":"inbound ...
Mandrill doc说,不应该包含分隔符,所以这是我正在使用的字符串(没有=
):
mandrill_events[{"event":"inbound ...
有关于此的任何想法吗?
PS:我仔细检查了网址和Webhook密钥: - )。
答案 0 :(得分:3)
使用https://mandrillapp.com/settings/webhooks中针对该特定Webhook显示的网址(示例中为config.url
)和密钥(config.key
)。
除了上述响应之外,您还必须确保使用单个反斜杠转义正斜杠。
// mandrillEventsParamVal - how you get that depends on your request processor chain
var paramValEscaped = mandrillEventsParamVal.replace(/\//g, '\\\/');
var input = config.url + 'mandrill_events' + paramValEscaped;
var check = crypto.createHmac('sha1', config.key).update(input, 'utf8', 'binary').digest('base64');
名为check
的字符串是您根据标题'X-Mandrill-Signature'检查的。
答案 1 :(得分:1)
问题来自您的输入数据格式。你必须连接键/值对,例如:
var data = URL; for(POST_DATA中的var键) data + = key + POST_DATA [key];
现在,您可以检查base64(sha1(data,mkey))是否等于签名。