登錄鑑權
WebSocket 行情推送連接建立後,需要先發送登錄鑑權幀。鑑權成功前不要發送訂閲請求;鑑權失敗、連接關閉或超時未返回鑑權結果時,應關閉當前連接,修正憑證後重新連接並重新鑑權。
INFO
本文描述的是當前 WebSocket 接入層支持的鑑權幀形態。後端行情訂閲服務本身不直接校驗公網訪問憑證,而是接收接入層完成鑑權後的會話上下文。因此,開發者只需要關注 WebSocket 連接後的首幀鑑權、鑑權結果處理和後續訂閲流程,不需要也不應傳入內部會話字段。
前置條件
開始前請確認已經完成以下準備:
- 已根據 快速開始 獲取可用的訪問憑證。
- 已連接 WebSocket Quote 地址:
wss://webapi-quote.moomoo.com- 當前賬號已具備對應市場、品類和行情檔位權限。權限會影響可訂閲的數據類型、買賣盤深度和實際推送內容。
鑑權方式
WebSocket 行情推送支持兩類接入方式:
| 方式 | 推薦程度 | 適用場景 | 說明 |
|---|---|---|---|
| OAuth 2.1 + PKCE | 推薦 | 第三方應用、桌面應用、移動端應用、Web 應用等需要用户授權的場景 | 使用 access_token 作為 Bearer Token 完成 WebSocket 登錄鑑權。 |
| API Key | 兼容 | 服務端自有系統、後端任務、內部工具等由開發者自行管理密鑰的場景 | 使用 AppKey、時間戳、隨機串和簽名完成 WebSocket 登錄鑑權。 |
推薦使用 OAuth
OAuth 方式無需在客户端保存 API 私鑰,也無需為每次接入手工管理簽名材料。除非已有服務端 API Key 接入或有明確兼容需求,建議優先使用 OAuth 2.1 + PKCE。
鑑權幀格式
連接建立後,客户端應將鑑權幀作為首個業務消息發送:
| 字段 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 auth。 |
data.auth_type | string | 是 | 鑑權類型。OAuth 使用 oauth2,API Key 使用 appkey。 |
data.authorization | string | 是 | OAuth 場景傳 Bearer {access_token};API Key 場景傳簽名結果。 |
OAuth 鑑權示例
先按 快速開始:OAuth 2.1 + PKCE 獲取 access_token,再在 WebSocket 連接打開後發送以下 JSON:
{
"action": "auth",
"data": {
"auth_type": "oauth2",
"authorization": "Bearer {access_token}"
}
}說明:
authorization必須包含Bearer前綴。access_token過期或無效時,鑑權會失敗。請使用refresh_token刷新後重新建立 WebSocket 連接並重新鑑權。- 請確認用户授權範圍覆蓋行情讀取能力;權限不足時,後續訂閲可能失敗或無法收到對應類型的數據。
Token 安全
不要把 access_token、refresh_token 寫入前端可公開訪問的靜態配置、日誌或錯誤上報。服務端應用應使用安全存儲;桌面或移動端應用應使用系統密鑰鏈、加密存儲等機制。
API Key 鑑權示例
API Key 方式適合服務端持有私鑰的場景。請先按 快速開始:傳統 API Key 創建 AppKey、上傳公鑰並安全保存私鑰。
WebSocket 鑑權幀的高層結構如下:
{
"action": "auth",
"data": {
"auth_type": "appkey",
"credential_id": "{app_key}",
"authorization": "{signature_base64}",
"timestamp_ms": 1782357937000,
"nonce": "{nonce}"
}
}字段說明:
| 字段 | 類型 | 必填 | 說明 |
|---|---|---|---|
credential_id | string | 是 | AppKey ID。 |
authorization | string | 是 | 使用 AppKey 私鑰生成的簽名結果,通常為 Base64 編碼後的簽名字符串。 |
timestamp_ms | int64 | 是 | 客户端當前毫秒時間戳。 |
nonce | string | 是 | 客户端隨機字符串,用於防重放。 |
API Key 簽名規則
WebSocket API Key 鑑權與 REST API Key 調用使用同一套 AppKey / 公鑰 / 私鑰身份體系,但簽名原文格式與 REST 不同。
WebSocket 鑑權簽名原文格式(字段間用 \n 分隔):
{timestamp_ms}\n{nonce}\nWEBSOCKET\nws/auth不要直接複用 REST 請求的簽名原文。
私鑰安全
API Key 私鑰只應保存在開發者自己的安全服務端或受控運行環境中。不要把私鑰下發到瀏覽器、移動端安裝包、客户端配置文件或代碼倉庫。
鑑權結果處理
客户端發送鑑權幀後,應等待服務端返回鑑權結果,再繼續發送訂閲請求。
建議按以下方式處理:
| 場景 | 處理建議 |
|---|---|
| 鑑權成功 | 記錄連接進入已鑑權狀態,然後發送訂閲請求。訂閲格式見 訂閲與反訂閲。 |
| 返回錯誤 | 不要繼續訂閲。根據錯誤信息檢查 Token、AppKey、簽名、時間戳、權限等配置。 |
| 服務端關閉連接 | 視為當前連接不可用。修正憑證或等待退避時間後重新連接、重新鑑權。 |
| 等待超時 | 主動關閉連接並重試。避免在未知鑑權狀態下發送訂閲請求。 |
鑑權成功響應
鑑權成功時,服務端返回以下 JSON:
{
"id": "req-001",
"session_id": "123456789",
"server_time": 1782357937000000
}| 字段 | 類型 | 說明 |
|---|---|---|
id | string | Echo 請求 ID,請求未傳時省略。 |
session_id | string | 服務端分配的會話 ID。 |
server_time | int64 | 服務器時間,微秒級時間戳。 |
當前接入層在鑑權成功後會建立後續訂閲所需的會話上下文。客户端無需解析或傳遞內部路由字段,例如 uid、session_id、conn_id、行情權限畫像或配額字段;這些字段由接入層和後端服務內部處理。
通道刷新
鑑權成功後,可在已建立的連接上發送刷新幀以更新會話票據。刷新成功後,已有訂閲不中斷,繼續正常推送。
刷新頻率要求
客户端應至少每 10 分鐘發送一次刷新幀。若超過 10 分鐘未主動刷新,服務端將主動斷開連接。建議以 5 分鐘為週期定時發送刷新幀,預留容錯次數。
OAuth 刷新
使用 refresh_token 在後台換取新的 access_token 後,發送以下刷新幀:
{
"action": "refresh",
"data": {
"authorization": "Bearer {new_access_token}"
}
}說明:
- 建議在 Token 過期前主動刷新,避免因 Token 失效導致會話中斷。
authorization必須包含Bearer前綴。
API Key 刷新
{
"action": "refresh",
"data": {
"credential_id": "{app_key}",
"authorization": "{new_signature_base64}",
"timestamp_ms": 1782357938000,
"nonce": "{new_nonce}"
}
}說明:
timestamp_ms和nonce必須使用與上次鑑權不同的新值,不能重複使用。- 簽名原文格式與初始鑑權相同:
{timestamp_ms}\n{nonce}\nWEBSOCKET\nws/auth。
刷新成功響應
刷新成功時,服務端返回與初始鑑權相同格式的響應:
{
"id": "req-002",
"session_id": "123456789",
"server_time": 1782357938000000
}session_id 保持不變,server_time 更新為當前服務器時間。
如果刷新失敗,請檢查新憑證是否有效;連續刷新失敗時,可關閉連接後用新憑證重新建立連接並重新鑑權。
與訂閲權限的關係
登錄鑑權只確認“當前連接是誰”和“憑證是否有效”。實際能否訂閲某個標的或數據類型,還會受到以下因素影響:
- 賬號是否具備對應市場和品類的行情權限。
- 行情權限檔位是否支持對應數據類型或深度,例如 LV1 / LV2 / LV3 對買賣盤深度的影響。
- 當前賬號或權限層級的訂閲配額是否足夠。
- 標的代碼是否有效,且是否支持對應推送類型。
因此,鑑權成功不等於所有訂閲都會成功。訂閲請求仍需要根據響應結果處理成功、失敗、權限不足和配額不足等情況。
連接生命週期建議
- 先鑑權再訂閲:每次新建 WebSocket 連接後,都應先發送鑑權幀,等待成功後再訂閲。
- 斷線後重新鑑權:連接斷開後不要假設原連接的鑑權狀態仍然有效。請重新連接、重新鑑權、重新訂閲。
- 定時發送刷新幀:鑑權成功後,客户端須每隔不超過 10 分鐘發送一次刷新幀,建議週期為 5 分鐘。超過 10 分鐘未刷新,服務端將主動斷開連接。OAuth 場景同時也應在 Token 過期前完成刷新;API Key 場景同樣需要定時刷新以維持會話。詳見 通道刷新。
- 不要複用內部會話字段:服務端返回或日誌中可能出現的會話標識僅用於接入層和後端路由,不應作為公開訂閲參數持久化或複用。
- 做好退避重試:連續鑑權失敗時,應檢查憑證配置並採用指數退避,避免高頻重連。
常見問題
可以在一個連接上重新發送鑑權幀切換用户嗎?
不建議。一個 WebSocket 連接應對應一次明確的登錄鑑權上下文。如需切換用户、賬號或憑證,請關閉舊連接,使用新憑證重新連接並重新鑑權。
OAuth 和 API Key 可以混用嗎?
單次連接請選擇一種鑑權方式。OAuth 方式使用 auth_type=oauth2 和 Bearer Token;API Key 方式使用 auth_type=appkey 和簽名材料。不要在同一條鑑權幀中同時傳兩套憑證。
鑑權成功後是否還需要在訂閲請求裏傳 Token?
不需要。鑑權成功後,後續訂閲請求使用已建立的連接會話上下文。訂閲請求只需要表達訂閲動作、標的和數據類型,不要重複傳入 Token、AppKey 或內部會話字段。
鑑權成功後為什麼訂閲仍然失敗?
常見原因包括:標的代碼無效、賬號沒有對應市場或品類權限、當前行情權限檔不支持該數據類型、訂閲配額不足,或請求中的 K 線週期 / 復權方式不合法。請結合 訂閲與反訂閲、錯誤碼 和 頻率與配額 排查。