用途:指导在应用中实现入站(对方调用你)与出站(你调用对方)Webhook,把 HTTP 当作通知通道而非交互界面。
入站主要能力:在原始 body 上校验 HMAC 或提供方密钥,若提供方对字节签名则不要先解析 JSON;拒绝过期时间戳以防重放,容差需文档化(如 5 分钟);用 Postgres 中 event_id 唯一约束实现幂等,重复事件返回 200 且不重复处理;快速返回 2xx,持久化后交给后台任务处理重活;secret 缺失时 fail closed;使用专用路由、HTTPS、按环境隔离 secret;仅在提供方与仓库已支持时再加 mTLS 或 IP 白名单;不要记录原始 payload,只记录 event_id、类型与结果。
出站主要能力:目标 URL 由资源所有者登记并使用 HTTPS,不做开放中继;用可轮换 secret 对 timestamp.payload 签名并文档化请求头;5xx 或网络错误按退避重试,4xx 不重试(死 URL 进 DLQ 或禁用端点);payload 稳定并带版本(v1),只传 ID 而非内部对象图;客户端超时短,任务设尝试上限。
幂等与顺序:入站可能重复且乱序,应按 event_id 与聚合状态应用,而非盲目“最后 JSON 获胜”;出站消费者应幂等,仍发送 idempotency-key 或 event_id;默认至少一次投递,不要仅靠 HTTP 承诺恰好一次。
安全:签名比较用常量时间;secret 只放环境变量或密钥管理;调用用户 URL 时若允许任意目标需屏蔽私有 IP 防 SSRF;轮换时入站校验保留 current 与 previous 两个 secret。
测试与运维:准备有效/无效签名与过期时间戳的 fixture,同一 event_id 重放应返回 200 空操作;staging 用独立 secret,不要把生产提供方指向 localhost;监控投递量、HMAC 失败与出站 DLQ,入站 401/400 激增时告警。
反模式:校验 HMAC 前返回 200、在请求内处理 30 秒、记录完整 req.body、对 400 无限重试、用 GET 做 Webhook、单一 /webhook 路由不区分提供方与 secret。
与其他技能配合:队列用 background-jobs,领域事件用 event-driven-architecture,HTTP 用 api-design,授权用 authentication-authorization。完成标准:入站有 HMAC 与时间戳且快速 2xx,event_id 唯一且重复为空操作,出站签名且仅对瞬时错误重试并设任务上限,日志无 PII,按环境隔离 secret 并使用 HTTPS。