javascript – 使用Node.js,Express和Trialpay进行HMAC MD5验证

我正在尝试使用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]"));

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...