简体   繁体   English

使用 HMAC sha256 和 base64 编码请求正文

[英]Encoding request body with HMAC sha256 and base64

How to encode a request body using HMAC sha 256 and base64.如何使用 HMAC sha 256 和 base64 对请求正文进行编码。

The request object that i receives from xero webhook.我从 xero webhook 收到的请求 object。

HEADER:
   "x-xero-signature" : HASH_VALUE
PAYLOAD:
  {
     "events": [],
     "lastEventSequence": 0,
     "firstEventSequence": 0,
     "entropy": "S0m3r4Nd0mt3xt"
  } 

The note from xero documentation says "If the payload is hashed using HMACSHA256 with your webhook signing key and base64 encoded, it should match the signature in the header. This is a correctly signed payload. If the signature does not match the hashed payload it is an incorrectly signed payload." xero 文档中的注释说:“如果使用 HMACSHA256 对有效负载进行哈希处理,并使用您的 webhook 签名密钥和 base64 编码,它应该与 header 中的签名匹配。这是一个正确签名的有效负载。如果签名与哈希有效负载不匹配,则它是签名错误的有效载荷。”

And I followed this example: https://devblog.xero.com/using-xero-webhooks-with-node-express-hapi-examples-7c607b423379我遵循了这个例子: https://devblog.xero.com/using-xero-webhooks-with-node-express-hapi-examples-7c607b423379

const express = require("express");
const router = express.Router();
const base64 = require('base-64');
const crypto = require('crypto')
const bodyParser = require('body-parser')
const xero_webhook_key = '00fRRlJBYiYN4ZGjmTtG+g/pulyb1Eru68YYL3PFoLsa78dadfQtGrOMuISuVBHxpXeEYo0Yy1Gc+hHMhDkSI/EEcgtrA==';

let options = {
    type: 'application/json'
  };
let itrBodyParser = bodyParser.raw(options);

router.post("/", itrBodyParser, async (req, res, next) =>{
//     console.log('::::WebhookPost:::');
const reSign = req.headers['x-xero-signature'];
 console.log(req.headers['x-xero-signature']);
 console.log('::::::::');
 console.log(req.body);
    console.log("Body: "+JSON.stringify(req.body))
    console.log(req.body.toString());
    console.log("Xero Signature: "+ reSign);
    console.log('Server key::::',xero_webhook_key);
    // Create our HMAC hash of the body, using our webhooks key
    let hmac = crypto.createHmac("sha256", xero_webhook_key).update(req.body.toString()).digest('base64');
    console.log("Resp Signature: ",hmac)

    if (req.headers['x-xero-signature'] == hmac) {
        res.statusCode = 200
    } else {
        res.statusCode = 401
    }
    console.log("Response Code: "+res.statusCode)
    return res.send();
 

});

Hey I recently did a video on implementing webhooks with Xero, let me know if this gets you unstuck.嘿,我最近做了一个关于使用 Xero 实现 webhook 的视频,如果这让你不解,请告诉我。 I found that trying to pass itrBodyParser on the route the way you have wasn't working for me so I switched it with an app.use statement on my specific webhooks endpoint.我发现尝试以您的方式在路由上传递 itrBodyParser 对我不起作用,所以我在我的特定 webhooks 端点上使用 app.use 语句切换它。 If you prefer a written guide over video, here's the blog post如果您更喜欢书面指南而不是视频,这里是博客文章

I solved it using this solution.. I was using express framework and the request were not getting as raw request also.toString of didn't worked as mentioned in xero documentation.我使用这个解决方案解决了它。我使用的是 express 框架,请求也没有得到原始请求。toString of 没有像 xero 文档中提到的那样工作。

 const server = http.createServer(async (req, resp) => {
  try {
      console.log(`::::Webhook::: ${webhookPort}`);
      console.log("::::x-xero-signature:::");
      console.log(req.headers["x-xero-signature"]);
      console.log(`--------------------------------------`);
      if (req.method === "POST") {
        if(req.headers["x-xero-signature"]){
          const rData = await new Promise((resolve, reject) => {
            return collectRequestData(req, (result) => {
                
                console.log(result);
                let hmac = crypto
                  .createHmac("sha256", xero_webhook_key)
                  .update(result)
                  .digest("base64");
                  console.log("Resp Signature: ", hmac);
                 
               
                return resolve({
                  hmac,result
                });
              });
          });
           console.log(">>Resp Signature: ", rData);
           console.log('>>x-xero-signature:::',req.headers["x-xero-signature"]);
           if(rData.result){
             const result = JSON.parse(rData.result);
             console.log('result:::',result);
             for(let { resourceId } of result.events) {
              console.log('::INVOICE ID = ',resourceId);
                getInvoiceData(resourceId);
             }
           }

           if(rData.hmac == req.headers["x-xero-signature"] ){
            console.log('::YES');
              resp.statusCode = 200;
          }else{
            console.log('::NO');
            resp.statusCode = 401;
          }
        }
        resp.end();
      }

        console.log("::::Webhookgetsssss:::");
        resp.message = 'Get API'
        resp.end();
     
  } catch (error) {
    resp.statusCode = 200;
    resp.end();
  }
      
     
  });
  server.listen(webhookPort);

function collectRequestData(request, callback) {
    let body = "";
    request.on("data", (chunk) => {
      body += chunk.toString();
    });
    request.on("end", () => {
      callback(body);
    });
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM