首页 文章

WooCommerce Webhooks Auth(秘密和签名) - 如何使用

提问于
浏览
8

我正在尝试在WooCommerce Webhook API和我的Node.js后端之间创建集成 . 但是,我可以't really figure out how I'假设使用该秘密来验证请求 .

secret: 一个可选的密钥,用于生成请求正文的 HMAC-SHA256 哈希值,以便接收方可以验证webhook的真实性 .

X-WC-Webhook-Signature: 有效负载的Base64编码HMAC-SHA256哈希值 .

WooCommerce backend: (Hemmelighed = "Secret")
enter image description here

Nodejs backend:

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

router.post('/', function (req, res) {
    var secret = 'ciPV6gjCbu&efdgbhfgj&¤"#&¤GDA';
    var signature = req.header("x-wc-webhook-signature");
    var hash = CryptoJS.HmacSHA256(req.body, secret).toString(CryptoJS.enc.Base64);

    if(hash === signature){
        res.send('match');
    } else {
        res.send("no match");
    }

});

资料来源:https://github.com/woocommerce/woocommerce/pull/5941

WooCommerce REST API source

哈希和签名不匹配 . 怎么了?

Update: console.log 返回以下值:

hash :pU9kXddJPY9MG9i2ZFLNTu3TXZA 85pnwfPqMr0dg0 =

signature :PjKImjr9Hk9MmIdUMc pEmCqBoRXA5f3Ac6tnji7exU =

hash (without .toString(CryptoJS.enc.Base64)) :a54f645dd7493d8f4c1bd8b66452cd4eedd35d903efbce699f07cfa8caf4760d

1 回答

  • 1

    需要针对正文检查签名,而不是它包含的JSON . 即req.body的原始字节 .

    首先修改bodyParser:

    const rawBodySaver = (req, res, buf, encoding) => {
      if (buf && buf.length) {
        req.rawBody = buf.toString(encoding || 'utf8');
      }
    };
    
    app.use(bodyParser.json({ verify: rawBodySaver }));
    app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
    app.use(bodyParser.raw({ verify: rawBodySaver, type: '*/*' }));
    

    然后,使用crypto(它与节点一起分发,你不需要npm安装任何东西 . )

    import crypto from 'crypto'; //Let's try with built-in crypto lib instead of cryptoJS
    
    router.post('/', function (req, res) {
      const secret = 'ciPV6gjCbu&efdgbhfgj&¤"#&¤GDA';
      const signature = req.header("X-WC-Webhook-Signature");
    
      const hash = crypto.createHmac('SHA256', secret).update(req.rawBody).digest('base64');
    
      if(hash === signature){
        res.send('match');
      } else {
        res.send("no match");
      }
    });
    

相关问题