跳轉到內容

API 認證授權

概述

Taker API 使用 API Key + Secret 簽名認證方式。開發者必須使用其 API KeyAPI Secret 對每個請求進行簽名。簽名是透過將請求方法、請求路徑、時間戳記與請求參數/主體以 | 符號串接,然後應用 HMAC-SHA256 雜湊演算法生成的。簽名與相關元資料會包含在請求標頭中。伺服器會驗證簽名、驗證使用者身份,並授權後才處理請求。

認證流程

每個請求必須包含:

  • API Key
  • 時間戳記
  • 使用 API Secret 與請求內容計算的簽名

API 會驗證:

  1. API Key 是否有效且啟用中
  2. 簽名是否與請求內容匹配
  3. 時間戳記是否在允許的範圍內(預設誤差 ±5 分鐘)

若以上任一項驗證失敗,請求將返回錯誤碼,如:

json
{"code":10010008,"message":"Signature verification failed"}

必填請求標頭

所有經過身份驗證的 API 請求必須包含下列自訂標頭:

標頭名稱範例值說明
X-API-KeyA1B2C3D4E5F6...您的公用 API 金鑰
X-API-Signaturea8f9c3e...經 HMAC-SHA256 產生的簽名
X-API-Timestamp1715100000000當前的 UNIX 毫秒級時間戳

選填(建議用於追蹤)

標頭名稱範例值說明
X-REQUEST-IDuuid-string用戶端自定請求 ID,便於除錯與日誌關聯追蹤

簽名生成步驟

  1. 使用 大寫 的 HTTP 請求方法(例如:POST)。

  2. 接著使用 | 連接 API 路徑(不含網域與協議,必須以/開頭!如 /api/v1/orders)。

  3. 再接上 UNIX 毫秒級時間戳。

  4. 最後接上請求參數:

    • GET 請求:使用 key=value 串連的查詢參數(不含 ?),若無則為空字串。注意,請求的參數不要改變其順序,要確保簽署的和請求的參數是一致的。
    • 非 GET 請求:使用原始 JSON 字串作為 body,若無則為空字串。注意,請確保請求體和簽名的一致,不要因為類似格式化而改變,導致請求的和簽名的不是同一份正文。
  5. 最終簽名字串格式:

{request_method}|{request_path}|{timestamp}|{query_string_or_request_body}
  1. 使用 API Secret 對此簽名字串進行 HMAC-SHA256 加密。

  2. 將結果進行 Base64 編碼

  3. 將下列標頭加入請求:

    • X-API-Key
    • X-API-Timestamp
    • X-API-Signature

範例(簽名字串構造流程):

POST|/api/v1/orders/lock|1746774142003|{"order_hash":"0x1234..."}

最終簽名為:

Base64(HMAC-SHA256(signature_string, API_Secret))

代碼示例

python
import requests
import hmac
import hashlib
import base64
import time

class TakerApiClient:
    def __init__(self, api_key, api_secret, base_url):
        self.api_key = api_key
        self.api_secret = api_secret
        self.base_url = base_url

    def send_request(self, method, path, query_string='', body=''):
        timestamp = int(time.time() * 1000)  # 毫秒
        signature_string = self.build_signature_string(method, path, timestamp, query_string, body)
        signature = self.generate_signature(signature_string, self.api_secret)

        url = self.base_url + path
        if query_string:
            url += '?' + query_string

        headers = {
            'X-API-Key': self.api_key,
            'X-API-Timestamp': str(timestamp),
            'X-API-Signature': signature,
            'Content-Type': 'application/json'
        }

        if method.upper() == 'GET':
            response = requests.get(url, headers=headers)
        else:
            response = requests.request(method.upper(), url, headers=headers, data=body)

        return response.text

    def build_signature_string(self, method, path, timestamp, query_string, body):
        signature_string = f"{method.upper()}|{path}|{timestamp}"
        if method.upper() == 'GET':
            signature_string += f"|{query_string}"
        else:
            signature_string += f"|{body}"
        return signature_string

    def generate_signature(self, data, secret):
        key = secret.encode('utf-8')
        message = data.encode('utf-8')
        hmac_obj = hmac.new(key, message, hashlib.sha256)
        return base64.b64encode(hmac_obj.digest()).decode('utf-8')

# 使用示例
api_key = 'your_api_key_here'
api_secret = 'your_api_secret_here'
base_url = '{API_BASE_URL}'

client = TakerApiClient(api_key, api_secret, base_url)

# 鎖定訂單示例
lock_body = '{"order_hash":"0x1234...","lock_duration":300}'
response = client.send_request('POST', '/api/v1/orders/lock', body=lock_body)
print('鎖定響應:', response)

# 查詢訂單示例
query_response = client.send_request('GET', '/api/v1/orders', 'status=locked&page=1&page_size=20')
print('查詢響應:', query_response)

常見使用場景

鎖定訂單

bash
curl -X POST "{API_BASE_URL}/api/v1/orders/lock" \
     -H "X-API-Key: YOUR_API_KEY" \
     -H "X-API-Timestamp: 1715100000000" \
     -H "X-API-Signature: GENERATED_SIGNATURE" \
     -H "Content-Type: application/json" \
     -d '{"order_hash":"0x1234...","lock_duration":300}'

成交訂單

bash
curl -X POST "{API_BASE_URL}/api/v1/orders/fill" \
     -H "X-API-Key: YOUR_API_KEY" \
     -H "X-API-Timestamp: 1715100000000" \
     -H "X-API-Signature: GENERATED_SIGNATURE" \
     -H "Content-Type: application/json" \
     -d '{"order_hash":"0x1234...","fill_quantity":"100"}'

查詢訂單

bash
curl -X GET "{API_BASE_URL}/api/v1/orders?status=locked&page=1&page_size=20" \
     -H "X-API-Key: YOUR_API_KEY" \
     -H "X-API-Timestamp: 1715100000000" \
     -H "X-API-Signature: GENERATED_SIGNATURE"

錯誤碼

代碼消息說明解決方案
10010008Signature verification failed簽名不匹配檢查簽名生成邏輯,確保參數一致
10010009API key not foundAPI key 不存在驗證 API key 是否正確
10010010API key expiredAPI key 已過期聯繫管理員更新 API key
10010011Timestamp expired請求時間戳超出允許範圍確保系統時間同步,重新生成時間戳
10010012Missing required header缺少認證標頭確保包含所有必需標頭
401Unauthorized認證失敗檢查 API key 和簽名
403Forbidden無權限訪問資源聯繫管理員驗證權限

安全最佳實踐

API Key 管理

  1. 安全存儲

    • 永不在源代碼中硬編碼 API key
    • 使用環境變量或安全配置管理
    • 定期輪換 API key
  2. 訪問控制

    • 為不同環境使用不同的 API key(開發、測試、生產)
    • 如可能,實施 IP 白名單
    • 監控 API key 使用並設置警報
  3. Secret 保護

    • 永不在客戶端代碼中暴露 API secret
    • 永不在應用日誌中記錄 API secret
    • 所有 API 通信使用 HTTPS

簽名生成

  1. 時間戳驗證

    • 確保系統時間與 NTP 服務器同步
    • 適當處理時鐘偏差
    • 為重試請求重新生成簽名
  2. 參數一致性

    • 簽名生成後不要修改請求參數
    • GET 請求保持參數順序
    • 簽名生成後避免格式化 JSON body
  3. 錯誤處理

    • 為失敗請求實施指數退避
    • 記錄簽名驗證失敗以便調試
    • 時間戳過期時不要使用相同簽名重試

故障排除

問題:簽名驗證失敗

可能原因

  • API secret 不正確
  • 參數順序不匹配
  • JSON body 格式差異
  • 時間戳格式不正確

解決方案

  1. 驗證 API secret 是否正確
  2. 在哈希前記錄簽名字串
  3. 確保請求 body 與簽名 body 完全匹配
  4. 使用毫秒時間戳(非秒)

問題:時間戳過期

可能原因

  • 系統時鐘未同步
  • 請求發送時間過長
  • 重用舊簽名

解決方案

  1. 與 NTP 同步系統時間
  2. 為每個請求生成新簽名
  3. 減少網絡延遲

問題:API key 未找到

可能原因

  • API key 不正確
  • API key 已刪除或過期
  • 環境錯誤

解決方案

  1. 從管理面板驗證 API key
  2. 檢查是否使用正確環境(測試 vs 生產)
  3. 如 key 丟失請聯繫管理員

相關文檔