为什么 express.json 会影响验签
HMAC 针对字节计算。JSON 的空格、换行、转义和键顺序发生变化,都会得到完全不同的签名。业务代码可以使用解析后的对象,但签名计算必须使用解析前的 Buffer。
使用 verify 回调保存 Buffer
app.use(express.json({
verify: (req, _res, buffer) => {
req.rawBody = Buffer.from(buffer);
},
}));
app.post("/webhooks/github", (req, res) => {
verifyGitHubSignature(req.rawBody, req.headers);
// 验签通过后再使用 req.body
res.sendStatus(200);
});如果只需要在部分路由保留 Body,也可以把专用中间件挂载在 Webhook 路由之前,避免为所有 API 长期保存原始内容。
上线检查清单
- 限制请求体大小,避免超大 Payload。
- 先验签、后解析和处理业务。
- 使用恒定时间比较函数。
- 快速返回 2xx,把耗时业务放入队列。
- 使用事件 ID 实现幂等,防止重复处理。