登录鉴权
WebSocket 交易推送连接建立后,需要先发送登录鉴权帧。鉴权成功前不会推送任何交易事件;鉴权失败、连接关闭或超时未返回鉴权结果时,应关闭当前连接,修正凭证后重新连接并重新鉴权。
INFO
本文描述的是当前 WebSocket 接入层支持的鉴权帧形态。后端交易推送服务本身不直接校验公网访问凭证,而是接收接入层完成鉴权后的会话上下文。因此,开发者只需要关注 WebSocket 连接后的首帧鉴权、鉴权结果处理和后续事件接收,不需要也不应传入内部会话字段。
前置条件
开始前请确认已经完成以下准备:
- 已根据 快速开始 获取可用的访问凭证。
- 已连接 WebSocket Trade 地址:
wss://webapi-trade.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 更新为当前服务器时间。
如果刷新失败,请检查新凭证是否有效;连续刷新失败时,可关闭连接后用新凭证重新建立连接并重新鉴权。
连接生命周期建议
- 先鉴权再等待事件:每次新建 WebSocket 连接后,都应先发送鉴权帧,等待成功后再期待接收事件推送。
- 断线后重新鉴权:连接断开后不要假设原连接的鉴权状态仍然有效。请重新连接并重新鉴权。
- 定时发送刷新帧:鉴权成功后,客户端须每隔不超过 10 分钟发送一次刷新帧,建议周期为 5 分钟。超过 10 分钟未刷新,服务端将主动断开连接。OAuth 场景同时也应在 Token 过期前完成刷新;API Key 场景同样需要定时刷新以维持会话。详见 通道刷新。
- 不要复用内部会话字段:服务端返回或日志中可能出现的会话标识仅用于接入层和后端路由,不应作为公开参数持久化或复用。
- 做好退避重试:连续鉴权失败时,应检查凭证配置并采用指数退避,避免高频重连。
常见问题
可以在一个连接上重新发送鉴权帧切换用户吗?
不建议。一个 WebSocket 连接应对应一次明确的登录鉴权上下文。如需切换用户、账号或凭证,请关闭旧连接,使用新凭证重新连接并重新鉴权。
OAuth 和 API Key 可以混用吗?
单次连接请选择一种鉴权方式。OAuth 方式使用 auth_type=oauth2 和 Bearer Token;API Key 方式使用 auth_type=appkey 和签名材料。不要在同一条鉴权帧中同时传两套凭证。
鉴权成功后为什么收不到任何事件?
鉴权成功仅代表连接合法,不代表账户有待处理的事件。交易事件推送是被动触发的,有事件发生时服务端才会推送。如长时间未收到任何消息,可结合 连接保活 检查连接是否仍然健康。