WooCommerce Webhooks Auth (секрет и подпись) - как использовать

Я пытаюсь создать интеграцию между настраиваемые веб-перехватчик API-интерфейс и мой узел.JS и серверной. Однако я не могу понять, как я должен использовать секрет для аутентификации запроса.

secret: дополнительный секретный ключ, используемый для создания HMAC-SHA256 хэш тела запроса, чтобы получатель мог проверить подлинность webhook.

X-WC-Webhook-Signature: хэш HMAC-SHA256 в кодировке Base64 полезная нагрузка.

плагин WooCommerce бэкэнд: (Hemmelighed = "Секрет") enter image description here

бэкэнд Nodejs:

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 источник

хэш и подпись не совпадает. Что случилось?

обновление: console.log возвращает эти значения:

hash: pU9kXddJPY9MG9i2ZFLNTu3TXZA++85pnwfPqMr0dg0=

signature: PjKImjr9Hk9MmIdUMc+pEmCqBoRXA5f3Ac6tnji7exU=

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

1 ответов


подпись должна быть проверена против тела, а не JSON, который он содержит. т. е. необработанные байты req.тело.

изменить 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 install ничего.)

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");
  }
});