API Key 与 HMAC 签名¶
证据:ptrader-api-gateway/docs/API-Authentication-Mechanism.en.md、filter/AuthFilter.java、Postman 集合预请求脚本。
Header¶
| Header | 是否必需 | 说明 |
|---|---|---|
x-ptrader-apikey |
是(签名与仅 Key) | API Key |
true-client-ip / x-real-ip |
经 ingress 时常必需 | 客户端 IP;Postman 设置 true-client-ip |
签名请求¶
适用于带 @SignAuth 且非 validKeyOnly 的接口(下单、账户、钱包等)。
参数¶
| 参数 | 是否必需 | 说明 |
|---|---|---|
timestamp |
当 checkRecvWindow=true 时必需 |
Unix 毫秒 |
recvWindow |
否 | 默认 5000 ms,最大 60000 ms |
signature |
是 | HMAC-SHA256 十六进制(query 或 header) |
时间窗规则¶
当且仅当:
timestamp ≤ serverTime + 1000 且 serverTime - timestamp ≤ recvWindow
签名原文(originStr)¶
规则:
- Query:除
signature外全部参数,按发送顺序以key=value用&连接。 - Body:
application/json→ 紧凑 JSON 字符串(网关经 JacksonJsonNode.toString())。application/x-www-form-urlencoded→ 未出现在 query 中的表单字段(排除signature)。- Query 与 Body 之间无额外分隔符直接拼接。
可运行示例(LIMIT 下单,无 body)¶
示意凭证(来自 api-gateway 鉴权文档 — 非生产密钥):
- API Key:
vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A - API Secret:
NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j
API_KEY="vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A"
API_SECRET="NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
BASE_URL="https://api-gateway-scb.dev.pcrypto.com"
TIMESTAMP=$(python3 -c 'import time; print(int(time.time()*1000))')
QUERY="symbol=BTCUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=0.001&price=50000×tamp=${TIMESTAMP}&recvWindow=5000"
SIGNATURE=$(printf '%s' "${QUERY}" | openssl dgst -sha256 -hmac "${API_SECRET}" | awk '{print $2}')
curl -sS -X POST "${BASE_URL}/openapi/v1/order?${QUERY}&signature=${SIGNATURE}" \
-H "x-ptrader-apikey: ${API_KEY}" \
-H "true-client-ip: 1.2.3.4" \
-H "Content-Type: application/x-www-form-urlencoded"
若有 JSON body,将紧凑 JSON 字符串追加到 query 字符串之后构成 originStr(Postman:JSON.stringify(JSON.parse(raw)))。
仅 Key 接口(listenKey)¶
POST|PUT|DELETE /openapi/v1/userDataStream 使用 @SignAuth(validKeyOnly = true, accountOnly = true)。
证据:UserDataApiController;AuthFilter 在 validKeyOnly() 分支仅经 broker-security 校验 Key,不校验签名。
只需发送 x-ptrader-apikey(Postman 的 X-Skip-Sign 仅为客户端提示,网关不识别)。
机构解析¶
BrokerInterceptor 由 Host → broker apiDomain 得到 x-org-id。失败 → INVALID_PARAMETER(host)。