WooCommerce Webhooks Auth (secret and signature) - how to use

I am trying to create an integration between the WooCommerce web hosting API and my Node.js file. However, I cannot figure out how I can use the secret to authenticate the request.

secret: optional secret key that is used to generate the HMAC-SHA256 hash of the request body so that the recipient can authenticate the webcam.

X-WC-Webhook-Signature: HMAC-SHA256 hash memory hash encoded by Base64.

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

Source: https://github.com/woocommerce/woocommerce/pull/5941

WooCommerce REST API Source

Hash and signature do not match. What's wrong?

Update: console.log returns the following values:

hash : pU9kXddJPY9MG9i2ZFLNTu3TXZA ++ 85pnwfPqMr0dg0 =

signature : PjKImjr9Hk9MmIdUMc + pEmCqBoRXA5f3Ac6tnji7exU =

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

+7
api wordpress hash woocommerce
source share
1 answer

The signature must be verified against the body, not the JSON contained in it. i.e. raw bytes of req.body .

First change 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: '*/*' })); 

and then using crypto (it is distributed using node you don't need npm install anything.)

 import crypto from 'crypto'; //Let 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"); } }); 

+1
source share

All Articles