# Webhook 集成
Webhook 功能允许外部系统(如 CI/CD 平台)通过 HTTP 请求触发 Git Manage Service 的同步任务。
# 接口信息
| 项目 | 值 |
|---|---|
| Endpoint | /api/webhooks/task-sync |
| Method | POST |
| Content-Type | application/json |
# 安全验证
# 签名验证
所有请求必须包含 X-Hub-Signature-256 请求头:
X-Hub-Signature-256: sha256=<hex_digest>
1
签名算法:
signature = hmac_sha256(secret_key, request_body)
1
# 频率限制
- 默认限制:100 请求/分钟
- 超出限制返回:
429 Too Many Requests
# IP 白名单(可选)
在配置文件中设置允许的 IP 列表:
webhook:
ip_whitelist:
- "192.168.1.0/24"
- "10.0.0.1"
1
2
3
4
2
3
4
# 请求格式
# 请求头
| Header | 值 | 说明 |
|---|---|---|
| Content-Type | application/json | 必需 |
| X-Hub-Signature-256 | sha256=... | 签名验证 |
# 请求体
{
"task_id": 1
}
1
2
3
2
3
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| task_id | uint | 是 | 要触发的同步任务 ID |
# 响应格式
# 成功响应 (200 OK)
{
"message": "Sync triggered successfully",
"task_id": 1
}
1
2
3
4
2
3
4
# 错误响应
| 状态码 | 说明 |
|---|---|
| 400 | 请求体格式错误或缺少参数 |
| 401 | 签名无效或缺失 |
| 403 | IP 不在白名单中 |
| 404 | 任务不存在 |
| 429 | 请求过于频繁 |
# 调用示例
# Python
import hmac
import hashlib
import json
import requests
SECRET = b'my-secret-key'
URL = 'http://localhost:38080/api/webhooks/task-sync'
DATA = {'task_id': 1}
body = json.dumps(DATA).encode('utf-8')
signature = 'sha256=' + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
headers = {
'Content-Type': 'application/json',
'X-Hub-Signature-256': signature
}
response = requests.post(URL, data=body, headers=headers)
print(response.status_code, response.text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Go
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
)
func main() {
secret := []byte("my-secret-key")
url := "http://localhost:38080/api/webhooks/task-sync"
body := []byte(`{"task_id": 1}`)
mac := hmac.New(sha256.New, secret)
mac.Write(body)
signature := "sha256=" + hex.EncodeToString(mac.Sum(nil))
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Hub-Signature-256", signature)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# cURL
# 先计算签名
# echo -n '{"task_id": 1}' | openssl dgst -sha256 -hmac "my-secret-key"
curl -X POST http://localhost:38080/api/webhooks/task-sync \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=<calculated_signature>" \
-d '{"task_id": 1}'
1
2
3
4
5
6
7
2
3
4
5
6
7
# GitHub Actions
name: Trigger Sync
on:
push:
branches: [main]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Trigger Git Manage Service
run: |
body='{"task_id": 1}'
signature=$(echo -n "$body" | openssl dgst -sha256 -hmac "${{ secrets.WEBHOOK_SECRET }}" | sed 's/.*= //')
curl -X POST ${{ secrets.GMS_URL }}/api/webhooks/task-sync \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=$signature" \
-d "$body"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 配置说明
# 配置文件
webhook:
secret: my-secret-key # 签名密钥
rate_limit: 100 # 频率限制(请求/分钟)
ip_whitelist: [] # IP 白名单
1
2
3
4
2
3
4
# 获取任务 ID
任务 ID 可以在同步任务列表中查看,或通过 API 获取。
# 最佳实践
- 密钥管理: 使用环境变量或密钥管理服务存储 Webhook Secret
- 错误处理: 实现重试逻辑,处理临时网络故障
- 日志记录: 记录所有 Webhook 调用,便于排查问题
- 超时设置: 设置合理的请求超时时间