mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
feat(reliability): idempotency store, custom webhook replay protection, correlation ids
Add LICENSE (MIT), an IdempotencyStore abstraction with a KV implementation and provider-scoped delivery keys, optional replay protection for custom webhooks (X-WebHooker-Timestamp + X-WebHooker-Nonce), and per-request correlation ids in webhook responses and logs.
This commit is contained in:
parent
92ba2203a5
commit
737dd7af98
15 changed files with 378 additions and 26 deletions
|
|
@ -94,7 +94,7 @@ POST /webhook
|
|||
|
||||
### 自定义 Webhook
|
||||
|
||||
任意 JSON 载荷用 `X-WebHooker-Signature: sha256=<hex>`(对原始 body 的 HMAC-SHA256,使用分组或全局 secret)签名后即可成为 `custom` 事件。用 `event: custom` 过滤器的路由接收。载荷格式见[配置 → 自定义 Webhook](../guide/ingress.md#自定义-webhook)。
|
||||
任意 JSON 载荷用 `X-WebHooker-Signature: sha256=<hex>`(对原始 body 的 HMAC-SHA256,使用分组或全局 secret)签名后即可成为 `custom` 事件。用 `event: custom` 过滤器的路由接收。可选的 `X-WebHooker-Timestamp` + `X-WebHooker-Nonce` 请求头启用重放防护(对 `{timestamp}.{nonce}.{body}` 签名、±5 分钟窗口、nonce 去重)。载荷格式见[配置 → 自定义 Webhook](../guide/ingress.md#自定义-webhook)。
|
||||
|
||||
### GitHub App 安装事件
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,32 @@ Gitea 载荷会被归一化为与 GitHub 事件相同的内部结构,因此路
|
|||
|
||||
- 支持任意提供方:GitHub(`X-Hub-Signature-256`)、Gitea(`X-Gitea-Signature`)、自定义(`X-WebHooker-Signature`)
|
||||
- 密钥为 64 位 hex 字符串;在控制台重新生成会立即失效旧密钥
|
||||
- 投递 id 去重键按租户隔离(`delivery:{groupId}:{id}`)
|
||||
- 投递 id 去重键按提供方与租户隔离(`delivery:{provider}:{groupId}:{id}`)
|
||||
- 分组没有密钥(或已不存在)时端点返回 `404`
|
||||
|
||||
## 自定义 Webhook
|
||||
|
||||
向 `POST /webhook/{groupId}`(或全局端点)POST 任意 JSON,并使用分组密钥将原始 body 的 HMAC-SHA256 以 `X-WebHooker-Signature: sha256=<hex>` 签名。载荷会变成 `custom` 事件,走正常的路由管线——创建一条 `event: custom` 的路由(控制台有模板),即可分发到该路由的目标、记录 `send_logs`,并出现在分组的 webhook 日志频道中。
|
||||
|
||||
### 重放防护
|
||||
|
||||
自定义 webhook 支持可选的防重放机制,在签名之外再附带两个请求头:
|
||||
|
||||
- `X-WebHooker-Timestamp` — 请求发送时的 Unix 秒数
|
||||
- `X-WebHooker-Nonce` — 每次请求唯一且不可预测的值(如 UUID)
|
||||
|
||||
当**同时**提供这两个请求头时,签名改为对 `{timestamp}.{nonce}.{原始body}` 计算(而非仅原始 body),且仅当以下条件满足时才被接受:
|
||||
|
||||
1. 时间戳与服务器时钟相差不超过 ±5 分钟(拒绝重放与时钟漂移滥用)
|
||||
2. nonce 从未被使用过(存入 KV 保留 10 分钟;重放的 nonce 会被拒绝)
|
||||
|
||||
```bash
|
||||
input="${timestamp}.${nonce}.${body}"
|
||||
signature="sha256=$(printf '%s' "$input" | openssl dgst -sha256 -hmac "$secret" -hex | sed 's/.*= //')"
|
||||
```
|
||||
|
||||
省略这些请求头时,WebHooker 回退到旧版的仅对 body 签名,现有发送方无需改动即可继续工作。
|
||||
|
||||
载荷模式:
|
||||
|
||||
```json
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue