HTTP API 鉴权
每次访问 https://openapi.abetterchoice.ai/abc/... 都需带三个 header,用来证明调用方持有合法的 API token。签名由 token、key 名、当前 Unix 时间戳每次重新计算。
Header
| Header | 说明 |
|---|---|
X-Ak | Settings → SDK&Key 中 API key 的名称,不是 token 本身。 |
X-Et | 当前 Unix 时间戳(秒),如 1748520000 对应 2025-05-29 11:20:00 UTC。 |
X-Es | token + ak + et 的 MD5 十六进制签名。 |
token 永远不会出现在请求中。线上传输的只有 key 名(ak)、时间戳(et)和签名(es), 所以泄漏的请求行在 token 轮转后无法被重放。
计算签名
signature = lowercase_hex(MD5(token || ak || et))其中:
token来自Settings → SDK&Key中该行的Token列;ak来自同一行的Name列;et是当前 Unix 时间戳(秒)。
Bash
bash
ak="your_secret_key_name"
token="your_api_token"
et=$(date +%s)
signature=$(echo -n "${token}${ak}${et}" | md5)
echo "X-Ak: $ak"
echo "X-Et: $et"
echo "X-Es: $signature"macOS 用
md5;Linux 用md5sum | awk '{print $1}',输出十六进制串相同。
Python
python
import hashlib, time
ak = "your_secret_key_name"
token = "your_api_token"
et = str(int(time.time()))
sig = hashlib.md5(f"{token}{ak}{et}".encode()).hexdigest()
headers = { "X-Ak": ak, "X-Et": et, "X-Es": sig }Go
go
import (
"crypto/md5"
"encoding/hex"
"fmt"
"time"
)
ak := "your_secret_key_name"
token := "your_api_token"
et := fmt.Sprintf("%d", time.Now().Unix())
sum := md5.Sum([]byte(token + ak + et))
sig := hex.EncodeToString(sum[:])Node.js
javascript
const crypto = require("node:crypto");
const ak = "your_secret_key_name";
const token = "your_api_token";
const et = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHash("md5").update(token + ak + et).digest("hex");拼到一起
bash
curl -X POST 'https://openapi.abetterchoice.ai/abc/get_experiments' \
-H "Content-Type: application/json" \
-H "X-Ak: $ak" -H "X-Et: $et" -H "X-Es: $signature" \
-d '{"project_id":"6666","unit_id":"user_id_1"}'header 正确时 ret_code: 100 并带回数据,详见 端点。
常见鉴权错误
| 现象 | 可能原因 |
|---|---|
ret_code: 101(无权限) | X-Ak 不属于该项目,或这把 key 已 Deactivated。 |
| 时间戳过期被拒 | 服务端时钟与你机器的时钟差超过允许窗口。NTP 同步后重新签名。 |
| 签名不一致 | 拼接顺序错(必须 token + ak + et),或者签错了 token。 |
安全最佳实践
- 绝不将 token 提交到代码仓库。每把 key 都搭配一个 secrets 管理器(Vault、AWS Secrets Manager、腾讯云 SSM 等),在部署时注入。
- 每个使用者一把 key ——
server_prod、server_staging、http_batch,泄漏哪个就停哪个。 - 先轮转,再停用。Deactivation 立即生效;新 key 也立即可用。先把新 key 铺开,确认流量 健康,再停老 key。完整流程见 API 密钥。
- 把时间戳当作 freshness token —— 在调用进程里现签现发,不要预先批量算签名再四处传。