标准答案

  1. 验证来源时应校验 HMAC 签名、时间戳、密钥版本、证书或 mTLS,并使用原始请求体参与验签,防止解析或重编码后签名不一致。
  2. 以事件 ID、事件来源和事件类型建立持久化去重记录。重复事件应返回成功或已处理状态,而不是再次执行业务副作用。
  3. 收到回调后优先快速确认,并将可靠处理放入队列或后台任务;长时间同步处理会触发对方超时并导致更多重试。
  4. 事件可能乱序到达,应以事件时间、版本号、资源当前状态或向源系统查询的权威状态决定是否应用,不能只按到达顺序覆盖。
  5. 需要记录原始事件的安全摘要、处理结果、失败原因和重放能力,以便对账和故障恢复。

题目解析

Webhook 不是可靠的数据库同步通道。网络失败、供应商重试、重复投递和事件丢失都需要在业务层通过查询、对账或补偿处理。

验签只验证事件来自某个密钥持有方,不代表事件在当前业务状态下仍应被执行;状态机和幂等仍然必要。

代码示例

验签、去重和异步入队应在接收入口完成,业务副作用由后续可重试处理器执行。

TypeScript
verifyHmac(rawBody, headers.signature, secret)
assertFreshTimestamp(headers.timestamp)

const inserted = await events.insertIfAbsent(headers.eventId)
if (inserted) await queue.publish({ eventId: headers.eventId })

return { status: 204 }

常见误区

  • 只校验来源 IP 或只信任一个可伪造 Header。
  • 同步执行完整业务后才返回 2xx,导致供应商不断重试。
  • 按收到顺序直接覆盖资源状态,不处理重复和乱序。

作者信息