pub struct AuthResult {
pub user_id: u64,
pub client_sig: Vec<u8>,
pub client_key: Vec<u8>,
pub user_attribution: UserAttribution,
pub auth_code_list: Vec<BrokerAuthCode>,
pub rand_key: Vec<u8>,
pub svr_time_offset: i64,
pub web_sig: String,
pub client_sig_invalid_local_time_s: u64,
pub moomoo_client_sig: Vec<u8>,
pub moomoo_client_key: Vec<u8>,
pub moomoo_web_sig: String,
}Fields§
§user_id: u64§client_sig: Vec<u8>§client_key: Vec<u8>§user_attribution: UserAttribution从 salt 响应拿到的归属地,TCP 登录时会用来派生 conn_identity
auth_code_list: Vec<BrokerAuthCode>HTTP auth 响应的 auth_code_list——每个已授权 broker 的票据,
用来后续向 /broker_auth/client_auth 换取 broker_client_sig / broker_client_key
rand_key: Vec<u8>原始 rand_key(解密用)——broker_auth 响应里的 broker_client_key 也是
用这个 rand_key 加密过的,需要它做 aes_cbc_md5_decrypt_var 解开
svr_time_offset: i64v1.4.22:服务端时间 - 本机时间(秒)—— salt 响应时捕获。
用于让后续 TOTP / time-based token 用“服务端时间“而不是本机时间。
机器时钟飘了 > 30s 的场景下 TOTP 会被服务端拒,offset 校正后可免。
对齐 C++ INNBiz_SvrTime::GetSvrTimeStamp() 机制。
使用方式:let server_now = local_now + svr_time_offset;
首次 salt 时 offset < 0 说明本机时钟比服务端快,反之则慢。0 = 没取到。
web_sig: Stringv1.4.93 G3 (CLAUDE.md C4 audit): web_sig from /authority/ 响应里的
web_sig_new 字段(对齐 C++ auth_impl.cpp:3193,3260
account.web_sig_)。
用途:G2 crate::auth::repull::repull_auth_code 把它作 POST
/authority/repull_auth_code body 字段(C++ auth_impl.cpp:738-748),
broker auth_code 过期时拉新 auth_code,让 broker channel self-heal
不必重启 daemon。
缺失 → 空字符串(旧 v1.4.92 及之前的凭据 / device-verify shell 路径 没此字段)。空时调用方应跳过 repull, fallback 走 platform refresh。
client_sig_invalid_local_time_s: u64v1.4.93 G1 (CLAUDE.md C4 audit P1): client_sig 失效的本地时戳 (秒, UTC epoch).
对齐 C++ auth_impl.cpp:3245-3247 解 cltsig_invalidtime (相对服务端时间秒)
svr_time得本地时间, 写到account.client_sig_invalid_local_time_s_.
用途: 记录服务端下发的 client_sig 失效时间。当前 auth 模块只负责 解析/持久化该字段,不启动 proactive timer;长跑 daemon 的 client_sig 更新走 reconnect 失败后的 reactive remember-login refresh 路径。
缺失 (老 backend / 旧 credentials shell): 0 (不触发 proactive refresh).
moomoo_client_sig: Vec<u8>v1.4.94 G6 (P2 protocol gap): moomoo_client_sig from /authority/
响应里的 moomoo_client_sig 字段, base64 已解码.
对齐 C++ auth_impl.cpp:3195 ParseJsonString(jval_result, "moomoo_client_sig", mm_sig);
映射到 account.us_client_sig_. 用于 moomoo / US 路径独立于
client_sig 的 broker channel 鉴权 — 当账号 attribution = US/SG/AU/JP/CA
时, broker_auth_code 换 client_sig 走的是 moomoo_client_sig 而不是
主 client_sig.
缺失 (futunn HK 账号 / 老 backend) → 空 Vec (handler 检查 is_empty()
决定 fallback 主 client_sig).
§⚠️ v1.4.96 BUG #010 doctrine fix (eli double-tester 2026-04-26):
真机 verify 发现 backend 对 futunn 账号也下发 moomoo_client_sig
(mm_sig_len=128). 字段名 moomoo_* 不意味着账号是 moomoo 系.
不要基于 moomoo_client_sig.is_empty() 判账号 broker path. 真正
的 broker path 判断用 broker_id (1001/1007=Futu HK/US, 6xxx=moomoo).
moomoo_client_key: Vec<u8>v1.4.94 G6 (P2 protocol gap): moomoo_client_key 解密后的 client key
(对应 moomoo path), 与 client_key 平级. 缺失 → 空 Vec.
对齐 C++ auth_impl.cpp:3196,3260 account.us_client_key_ (经
UpdateRandKey 解密).
moomoo_web_sig: Stringv1.4.94 G6 (P2 protocol gap): moomoo_web_sig_new from /authority/
响应. 对齐 C++ auth_impl.cpp:3197,3260 account.us_web_sig_. 用于
moomoo path repull_auth_code (类似 web_sig 之于主 path). 缺失 →
空字符串.
Trait Implementations§
Source§impl Clone for AuthResult
impl Clone for AuthResult
Source§fn clone(&self) -> AuthResult
fn clone(&self) -> AuthResult
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more