跳到主要内容

身份验证 (Authentication)

私有接口需要使用 Ethereum 钱包私钥进行签名。所有包含 signature 参数的请求都需要遵循以下流程。

签名规则

签名消息由以下部分按顺序拼接而成: timestamp + method + path + body

  • timestamp: 毫秒时间戳
  • method: HTTP 方法 (如 POST, GET, DELETE)
  • path: 接口路径 (如 /api/v1/orders)
  • body: 请求体 JSON 字符串 (如无 Body 则为空字符串)

签名算法

使用 secp256k1 曲线进行签名,消息需要使用 Ethereum 的 Personal Sign 格式。

Python 代码示例

import time
import json
from eth_account import Account
from eth_account.messages import encode_defunct

def sign_request(private_key, method, path, body=""):
timestamp = int(time.time() * 1000)

# 构造消息
message_text = f"{timestamp}{method}{path}{body}"
message = encode_defunct(text=message_text)

# 签名
signed_message = Account.sign_message(message, private_key=private_key)

return {
"signature": signed_message.signature.hex(),
"timestamp": timestamp
}

# 示例:创建订单签名
body = json.dumps({
"symbol": "BTCUSDT",
"side": "buy",
"order_type": "limit",
"amount": "0.1",
"price": "65000"
})
auth_data = sign_request("0x...", "POST", "/api/v1/orders", body)

请求头 (Headers)

虽然签名参数通常放在请求体中,但我们也支持通过 Headers 传递。

Header示例值
X-ZTDX-TIMESTAMP1630000000000

登录流程 (Login Flow)

对于需要持久化 Session 的应用,可以先进行登录。

1. 获取 Nonce

在使用私钥登录前,必须先获取一个随机的 nonce

请求

  • Method: GET
  • Path: /api/v1/auth/nonce/:address
  • 特性:
    • nonce 在成功登录后会 自增 1
    • 在未登录前多次调用,返回的 nonce 保持不变。

路径参数

参数类型必填描述
addressstringEthereum 地址(0x开头,42字符)

响应示例

{
"nonce": 1,
"message": "Sign this message to login to ZTDX.\n\nAddress: 0x742d35cc6634c0532925a3b844bc9e7595f0beb\nNonce: 1"
}

响应字段

字段类型描述
noncenumber当前用户的 nonce 值
messagestring需要签名的完整消息

2. 构建签名消息

您需要对以下格式的字符串进行签名:

Sign this message to login to ZTDX.

Address: {address}
Nonce: {nonce}

[!IMPORTANT]

  • {address} 必须为全小写。
  • 消息中的换行符和空格由于 Docusaurus 显示原因,请确保与上述模板完全一致。

3. 登录请求

请求

  • Method: POST
  • Path: /api/v1/auth/login
  • Content-Type: application/json

请求参数

参数类型必填描述
addressstringEthereum 地址(小写)
signaturestring对 nonce 消息的签名(0x开头)
timestampnumberUnix 时间戳(秒),需在5分钟内有效

请求示例

{
"address": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"signature": "0x...",
"timestamp": 1704067200
}

响应示例

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": 1704153600
}

响应字段

字段类型描述
tokenstringJWT 认证令牌
expires_atnumber令牌过期时间(Unix 时间戳)

错误响应

HTTP 状态码错误码描述
400TIMESTAMP_EXPIRED时间戳已过期
400INVALID_SIGNATURE_FORMAT签名格式无效
401SIGNATURE_INVALID签名验证失败
404USER_NOT_FOUND用户不存在,请先获取 nonce
500DATABASE_ERROR数据库错误
500JWT_GENERATION_FAILEDJWT 生成失败

使用 JWT Token

登录成功后,在所有需要认证的接口中,需要在请求头中携带 JWT Token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...