Webhook 签名验证

验证 `mr-signature` 请求头,确保 webhook 请求确实来自 ModelRiver。通过 HMAC-SHA256 防止伪造。

为什么要验证签名?

Webhook 端点是公开 URL。如果不做签名校验,任何人都可能向你的端点发送伪造载荷。ModelRiver 会使用 HMAC-SHA256 对每个 webhook 进行签名,你应在后端验证其真实性。

工作原理

  1. ModelRiver 使用你的 webhook secret 对载荷计算 HMAC-SHA256
  2. 签名会放在 mr-signature 请求头中
  3. 你的后端使用相同 secret 计算签名
  4. 如果两者一致,则说明请求可信

Node.js 实现

JAVASCRIPT
1const crypto = require('crypto');
2 
3function verifyWebhookSignature(payload, signature, secret) {
4 const expectedSignature = crypto
5 .createHmac('sha256', secret)
6 .update(JSON.stringify(payload))
7 .digest('hex');
8 
9 return crypto.timingSafeEqual(
10 Buffer.from(signature),
11 Buffer.from(expectedSignature)
12 );
13}

Python 实现

PYTHON
1import hmac
2import hashlib
3import json
4 
5def verify_webhook_signature(payload, signature, secret):
6 expected_signature = hmac.new(
7 secret.encode('utf-8'),
8 json.dumps(payload).encode('utf-8'),
9 hashlib.sha256
10 ).hexdigest()
11 
12 return hmac.compare_digest(signature, expected_signature)

安全最佳实践

  1. 始终验证签名:未校验 mr-signature 前不要处理 webhook
  2. 使用 timing-safe 比较:避免时序攻击
  3. 使用 HTTPS:生产环境中仅接收 HTTPS 端点
  4. 实现幂等性:用 channel_id 去重,防止重复投递造成副作用
  5. 设置合理超时:10 秒内快速响应,耗时逻辑放到后台任务
  6. 安全存储 secret:用环境变量或密钥管理系统,不要写入代码

下一步