开发者门户
认证与签名
请求头与签名算法
所有请求须携带以下四个请求头;签名用于防篡改与防重放。
请求头
| X-Api-Key | 平台分配的 API Key |
|---|---|
| X-Timestamp | Unix 秒级时间戳 |
| X-Nonce | 一次性随机串,防重放 |
| X-Signature | HMAC-SHA256 签名值 |
签名算法
signature = HMAC-SHA256( method + path + sha256(body) + timestamp + nonce , api_secret )
示例代码
TS=$(date +%s)
NONCE=$(openssl rand -hex 16)
BODY='{"author":"某某","era":"当代·2025年"}'
BODYHASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $2}')
SIGN=$(printf '%s' "POST/api/v1/filing${BODYHASH}${TS}${NONCE}" \
| openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $2}')
curl -X POST https://api.artstack.cn/api/v1/filing \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TS" \
-H "X-Nonce: $NONCE" \
-H "X-Signature: $SIGN" \
-H "Content-Type: application/json" \
-d "$BODY"import hmac, hashlib, time, secrets, json, requests
api_key = "ak_demo_xxx"
api_secret = "sk_demo_xxx"
path = "/api/v1/filing"
body = json.dumps({"author": "某某", "era": "当代·2025年"},
ensure_ascii=False, separators=(",", ":"))
ts = str(int(time.time()))
nonce = secrets.token_hex(16)
body_hash = hashlib.sha256(body.encode()).hexdigest()
msg = f"POST{path}{body_hash}{ts}{nonce}"
sig = hmac.new(api_secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
r = requests.post(
"https://api.artstack.cn" + path,
data=body.encode(),
headers={
"X-Api-Key": api_key,
"X-Timestamp": ts,
"X-Nonce": nonce,
"X-Signature": sig,
"Content-Type": "application/json",
},
)
print(r.status_code, r.json())const crypto = require('crypto');
const apiKey = 'ak_demo_xxx';
const apiSecret = 'sk_demo_xxx';
const path = '/api/v1/filing';
const body = JSON.stringify({ author: '某某', era: '当代·2025年' });
const ts = String(Math.floor(Date.now() / 1000));
const nonce = crypto.randomBytes(16).toString('hex');
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const msg = `POST${path}${bodyHash}${ts}${nonce}`;
const signature = crypto.createHmac('sha256', apiSecret).update(msg).digest('hex');
fetch('https://api.artstack.cn' + path, {
method: 'POST',
headers: {
'X-Api-Key': apiKey,
'X-Timestamp': ts,
'X-Nonce': nonce,
'X-Signature': signature,
'Content-Type': 'application/json',
},
body,
}).then((r) => r.json()).then(console.log);拼接顺序与注意事项
拼接顺序
method + path + sha256(body) + timestamp + nonce,各段无分隔符直接拼接。
时间戳
使用 Unix 秒级时间戳;与服务端时差过大将返回 TIMESTAMP_EXPIRED。
Nonce 防重放
每次请求使用一次性随机串,重复 Nonce 将被拒绝。
演示环境中的 Key(ak_demo_xxx / sk_demo_xxx)为示意值,非真实可用凭据。