Skip to main content

AuthResult

Struct AuthResult 

Source
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: i64

v1.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: String

v1.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: u64

v1.4.93 G1 (CLAUDE.md C4 audit P1): client_sig 失效的本地时戳 (秒, UTC epoch). 对齐 C++ auth_impl.cpp:3245-3247cltsig_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: String

v1.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

Source§

fn clone(&self) -> AuthResult

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AuthResult

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more