如何使用Node.js验证Shopify Webhook API

时间:2020-04-05 06:21:46

标签: node.js shopify shopify-api-node

我无法使用“ shopify-node-api”来验证来自shopify的webhook响应。我正在使用以下代码来验证签名。

下面的代码在app.js上

for count in range (1, numYears +1):
    increment = propValue * rate
    endVal = propValue + increment
    strEndVal = '$ ' + f'{endVal:,.2f}'
    print (f'{count:>5}  {strEndVal :>15}')
    propValue= endVal

下面是webhook.router.js

app.use(bodyParser.json({
type:'application/json',
limit: '50mb',
verify: function(req, res, buf, encoding) {
     if (req.url.startsWith('/webhook')){
         req.rawbody = buf;
     }
   }
 })
);
app.use("/webhook", webhookRouter);

下面的验证功能

router.post('/orders/create', verifyWebhook, async (req, res) => {    
    console.log('? We got an order')
    res.sendStatus(200)
 });

验证签名功能

function verifyWebhook(req, res, next) {
  let hmac;
  let data;
  try {
    hmac = req.get("X-Shopify-Hmac-SHA256");
    data = req.rawbody;
  } catch (e) {
    console.log(`Webhook request failed from: ${req.get("X-Shopify-Shop-Domain")}`);
    res.sendStatus(200);
  }
  if (verifyHmac(JSON.stringify(data), hmac)) { // Problem Starting from Here
    req.topic = req.get("X-Shopify-Topic");
    req.shop = req.get("X-Shopify-Shop-Domain");
    return next();
  }

  return res.sendStatus(200);
}

和我得到的身体未定义。建议我如何在shopify webhook API中解决此问题

1 个答案:

答案 0 :(得分:0)

不是使用bodyparser.json(),而是使用bodyparser.raw获取所有有效负载来处理shopify webhook验证。

router.use(bodyparser.raw({ type: "application/json" }));

// Webhooks
router.post("/", async (req, res) => {
  console.log("Webhook heard!");
  // Verify
  const hmac = req.header("X-Shopify-Hmac-Sha256");
  const topic = req.header("X-Shopify-Topic");
  const shop = req.header("X-Shopify-Shop-Domain");

  const verified = verifyWebhook(req.body, hmac);

  if (!verified) {
    console.log("Failed to verify the incoming request.");
    res.status(401).send("Could not verify request.");
    return;
  }

  const data = req.body.toString();
  const payload = JSON.parse(data);
  console.log(
    `Verified webhook request. Shop: ${shop} Topic: ${topic} \n Payload: \n ${data}`
  );

  res.status(200).send("OK");
});

// Verify incoming webhook.
function verifyWebhook(payload, hmac) {
  const message = payload.toString();
  const genHash = crypto
    .createHmac("sha256", process.env.API_SECRET)
    .update(message)
    .digest("base64");
  console.log(genHash);
  return genHash === hmac;
}