5.1 认证、签名与工作区
5.1 认证方式
dwz-server 支持两种认证方式。内网和测试场景推荐 Bearer Token;生产外联推荐 HMAC 签名。
方式一:Bearer Token
获取 Token
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}
响应:
{
"code": 0,
"data": {
"token": "eyJhbGciOi...",
"expire_at": "2026-04-16T10:00:00Z"
}
}使用 Token
Authorization: Bearer eyJhbGciOi...
curl 示例
TOKEN="eyJhbGciOi..."
curl -X POST http://localhost:8080/api/v1/short_links \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"original_url": "https://example.com"}'个人访问 Token
除登录 JWT 之外,可通过 POST /api/v1/tokens 创建长期有效的 个人访问 Token,同样以 Bearer 方式使用,适合脚本集成。可通过 DELETE /api/v1/tokens/{token_id} 随时吊销。
方式二:HMAC-SHA256 签名(推荐生产外联)
核心优势:App Secret 永远不上网,即使请求被截获也无法伪造签名。
请求头
| Header | 说明 |
|---|---|
X-App-Id |
应用标识 |
X-Signature |
HMAC-SHA256 签名(十六进制) |
X-Timestamp |
Unix 秒级时间戳,服务端允许 ±5 分钟偏差 |
X-Nonce |
随机字符串(16-32 字符),防重放 |
签名公式
signature = HMAC-SHA256(app_secret, string_to_sign)
string_to_sign = method + path + sorted_params_json + timestamp + noncemethod:HTTP 方法大写path:请求路径,如/api/v1/short_linkssorted_params_json:参数按 key 字母序排序后的 JSON- GET 使用 query
- POST/PUT/PATCH 使用 body
- 无参数用
{}
timestamp/nonce:与请求头一致
Python 签名实现
import hmac, hashlib, json, time, uuid, requests
APP_ID = "app_xxx"
APP_SECRET = "your_app_secret"
BASE = "http://localhost:8080"
def sign(method, path, params):
ts = str(int(time.time()))
nonce = uuid.uuid4().hex
params_json = json.dumps(params, sort_keys=True, separators=(",", ":"))
string_to_sign = f"{method}{path}{params_json}{ts}{nonce}"
sig = hmac.new(APP_SECRET.encode(), string_to_sign.encode(),
hashlib.sha256).hexdigest()
return {
"X-App-Id": APP_ID,
"X-Signature": sig,
"X-Timestamp": ts,
"X-Nonce": nonce,
}
body = {"original_url": "https://example.com", "title": "demo"}
headers = sign("POST", "/api/v1/short_links", body)
headers["Content-Type"] = "application/json"
r = requests.post(f"{BASE}/api/v1/short_links", headers=headers, json=body)
print(r.json())常见签名错误
40101/ 签名不匹配:确认 JSON 的 key 已按字母序排序、没有多余空白字符- 时间戳偏差:服务器与客户端时间差超过 5 分钟会拒绝
- nonce 重复:同一 nonce 在窗口内只能使用一次