我正在尝试使用Node.js和Express验证从TrialPay发送的消息. TrialPay使用HMAC-MD5哈希对请求进行签名,并在验证时提供
these instructions.
这是我的代码:
app.post('/trialpay',function(req,res) { var key = "[MY MERCHANT KEY]"; var hash = req.header("TrialPay-HMAC-MD5"); var data = req.body.toString(); var crypted = require("crypto").createHmac("md5",key) .update(data) .digest("hex"); if (hash == crypted) { res.writeHead(200,{"Content-Type": "plain/text"}); res.end("Success!"); } else { throw new Error("Invalid TrialPay Hash"); } });
显然,这不起作用(哈希不匹配).
免责声明:我对Node.js非常陌生,并且开始时只有很少的Javascript经验.
UPDATE
我没有意识到链接受到保护.
TrialPay uses your Notification-Key (set in your account information)
as the secret key to sign the HMAC. For GET requests the query string
that follows the question mark (in the URL) is signed. For POST
requests the entire POST body is signed.
以下是TrialPay如何指示您在Google App Engine(Python)中进行验证的示例:
class MyHandler(webapp.RequestHandler): def post(self): key = '[YOUR MERCHANT KEY]' tphash = self.request.headers['TrialPay-HMAC-MD5'] if hmacmd5(key,self.request.body) != tphash: logging.info('invalid trialpay hash') return
更新2
req.body打印出来:
{ oid: 'sample-order-id',sid: 'customer-sid',order_date: '04/24/2012',timestamp: '04/24/2012 16:28:46',first_name: 'customer-firstname',last_name: 'customer-lastname',email: 'customer@trialpay.com',revenue: '10.00',zip_code: '94041',country: 'US' }
解决方法
这应该是诀窍:
var crypto = require('crypto'); function calculateSignature(key) { return function(req,res,next) { var hash = req.header("TrialPay-HMAC-MD5"),hmac = crypto.createHmac("md5",key); req.on("data",function(data) { hmac.update(data); }); req.on("end",function() { var crypted = hmac.digest("hex"); if(crypted === hash) { // Valid request return res.send("Success!",{ "Content-Type": "text/plain" }); } else { // Invalid request return res.send("Invalid TrialPay hash",{ "Content-Type": "text/plain" },403); } }); req.on("error",function(err) { return next(err); }); } } app.post("/trialpay",calculateSignature("[MY MERCHANT KEY]"));