以 GitHub Webhook 为例,检查原始请求体验签、事件范围、持久化队列和重复事件处理,避免重试触发重复业务。

Webhook 接口可以触发部署、同步和订单状态更新,因此“地址没人知道”不能作为保护。一次可靠处理至少需要回答三件事:消息是否可信、当前事件是否允许处理、重复到达会不会产生第二次业务副作用。
验签必须发生在业务执行之前
以 GitHub 为例,官方文档使用共享秘密和 HMAC-SHA256 验证原始请求体,并建议采用安全的比较方式。中间件如果先解析再重新序列化 JSON,字节变化可能导致校验失败。秘密应放在受控配置中,不进入 URL、代码仓库或调试日志。
把接收成功与业务成功分开
验证通过后检查事件类型、动作与订阅范围。对耗时任务,可在事件可靠写入队列后按平台要求及时响应,再异步处理;不要在尚未持久化时就回成功,否则进程退出可能造成事件丢失。
为每个事件保存处理状态和业务幂等键,区分“已接收、处理中、已完成、可重试失败”。GitHub 文档说明重投会保留相同的 X-GitHub-Delivery;因此重投不应被当成新的业务动作。具体去重设计还要结合平台签名覆盖范围与业务唯一键,不能仅凭未经校验的头字段信任事件。
五个验收样本
- 合法消息:只产生一次预期结果。
- 正文变化或签名错误:拒绝进入业务队列。
- 合法但不订阅的事件:按设计忽略或拒绝。
- 相同事件重复到达:不重复扣减、通知或部署。
- 处理过程中重启:能从可靠状态恢复,且不会把未完成事件标记成功。
告警应能按事件标识定位失败环节,日志中只保留必要元数据。秘密轮换时应制定明确过渡窗口,验证旧配置退出,避免长期接受多个无人管理的密钥。
参考:GitHub:验证 Webhook 投递;Webhook 最佳实践。核对日期:2026年10月4日。
