我正在尝试创建一个 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()
,并尝试对示例有效负载进行硬编码,但这些都不起作用。
有什么想法吗?
您必须在 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');