Xero Webhook 验证(意图接收)- 响应不是 2XX

问题描述 投票:0回答:1

我正在尝试创建一个 Xero webhook 并将其连接到 Pipedream,但我无法让“接收意图”验证正常工作。我尝试了几种不同的方法(使用 Node.js)。这是我的第一次尝试:

import crypto from "crypto";

export default defineComponent({
  async run({ steps, $ }) {

    const key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          payload = steps.trigger.event.body.toString(),
          // payload = JSON.stringify({"events": [],"lastEventSequence": 0,"firstEventSequence": 0,"entropy": "S0m3r4Nd0mt3xt"}),
          calculatedHmac = crypto.createHmac('sha256', key).update(payload).digest('base64'),
          xeroSignature = steps.trigger.event.headers["x-xero-signature"];

        // console.log(calculatedHmac.trim());
        // console.log(xeroSignature);

    if (calculatedHmac.trim() === xeroSignature) {
      await $.respond({
        status: 200,
        headers: {},
        body: 'ok',
      })
    } else {
      await $.respond({
        status: 401,
        headers: {},
        body: 'unauthorised',
      })
    }
  },
})

这是我基于我发现的旧 GitHub 存储库的第二次尝试:

export default defineComponent({
  async run({ steps, $ }) {

    const { createHmac } = await import('crypto');
    const xero_webhook_key = 'xxxxxxxxxxxxxxxxxxxxxxxx'
    const body_string = JSON.stringify(steps.trigger.event.body)
    const xero_hash = steps.trigger.event.headers["x-xero-signature"]

    let our_hash = createHmac('sha256', xero_webhook_key).update(body_string).digest("base64") // Generate the hash Xero wants
    let statusCode = xero_hash == our_hash ? 200 : 401 // If the hashes match, send a 200, else send a 401

    await $.respond({
      status: statusCode
    });

  }
})

这两种方法每次都会返回

401
,即使从 Xero 发送了正确签名的签名也是如此。在第一批代码中,您会看到我使用
console.log
来显示计算出的 HMAC 和 Xero 签名,但它们从不匹配。

基于其他一些线程,我发现我也尝试过使用

.toString()
而不是
JSON.stringify()
,并尝试对示例有效负载进行硬编码,但这些都不起作用。

有什么想法吗?

node.js validation webhooks xero-api pipedream
1个回答
0
投票

您必须在 API 中允许原始正文请求类型。

这就是我使用 Nest JS 的方法:

    //main.ts
     const app = await NestFactory.create(AppModule, {rawBody: true});
    
    //webhook.controller.ts
     @Post()
     async xeroWebhookController (
        @Req() req: RawBodyRequest<Request>,
        @Res() res: Response
      ) {

    const rawPayload = query.rawBody.toString()
    const hmac = crypto.createHmac('sha256', this.config.xeroHashKey).update(rawPayload).digest('base64');
    }

和普通的 Express JS

//app.ts
//middleware
this.express.use("/api/3/xero-integrations/xeroWebhook", bodyParser.raw({ type: 'application/json', limit: '50mb' }), xeroWebhookController)

//xeroWebhook.controllers.ts
const hmac = crypto.createHmac('sha256', process.env.XERO_HASH_KEY).update(req.body.toString()).digest('base64');
© www.soinside.com 2019 - 2024. All rights reserved.