初步增加, 扫码登录成功
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
"""会话态模型:web_new_encrypt 离线生成所需的会话级输入。
|
||||
|
||||
F-2049/F-2051(E3):encrypt_msg 与当前会话绑定——
|
||||
- xMidasOps: goods.shtml 页面内嵌伪随机表(59640 值,服务端每次生成,页面级)
|
||||
- key16: goodsBiz VM 加载期 Math.random 前 16 次调用(页面级恒定)
|
||||
- key1: 诱饵密钥(点击级,捕获即可)
|
||||
服务端能验证 key 派生状态(随机 key 变体 ret:1099),因此新订单必须先捕获会话态。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_XMIDAS_TOKEN = "DE46DBA4754D42A6B66ADD4319FF80C144D9ED22ED73384C271793D9A9AA2FFBD6C104BE8D4A7F4ED2A8688FCB6F7540"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SessionState:
|
||||
"""一次 goods 页加载捕获的会话态。
|
||||
|
||||
xmidas_ops: list[int] 59640 项(页面级)
|
||||
key16: list[int] 16 字节(VM 加载期 Math.random 前 16 次)
|
||||
key1: list[int] 16 字节(诱饵)
|
||||
xmidas_token: str
|
||||
cookies: dict[str, str](提交 web_save 用,可选)
|
||||
openid/openkey: str(提交 web_save 用,可选)
|
||||
"""
|
||||
|
||||
xmidas_ops: list[int] = field(default_factory=list)
|
||||
key16: list[int] = field(default_factory=list)
|
||||
key1: list[int] = field(default_factory=list)
|
||||
xmidas_token: str = DEFAULT_XMIDAS_TOKEN
|
||||
args_template_d: str = "" # webSave 18 参深拷贝(deepcap PC 85091 的 C[2] 原始 D 编码,会话绑定)
|
||||
cookies: dict[str, str] = field(default_factory=dict)
|
||||
openid: str = ""
|
||||
openkey: str = ""
|
||||
source: str = "" # 捕获来源说明
|
||||
|
||||
def validate(self) -> list[str]:
|
||||
errs: list[str] = []
|
||||
if len(self.xmidas_ops) != 59640:
|
||||
errs.append(f"xmidas_ops 长度 {len(self.xmidas_ops)} != 59640")
|
||||
if len(self.key16) != 16:
|
||||
errs.append(f"key16 长度 {len(self.key16)} != 16")
|
||||
if len(self.key1) != 16:
|
||||
errs.append(f"key1 长度 {len(self.key1)} != 16")
|
||||
if not self.xmidas_token:
|
||||
errs.append("xmidas_token 为空")
|
||||
if not self.args_template_d:
|
||||
errs.append("args_template_d 为空(需 deepcap PC 85091 的 C[2] 原始 D 编码)")
|
||||
return errs
|
||||
|
||||
def to_json(self) -> dict:
|
||||
return {
|
||||
"xmidas_ops": self.xmidas_ops,
|
||||
"key16": self.key16,
|
||||
"key1": self.key1,
|
||||
"xmidas_token": self.xmidas_token,
|
||||
"args_template_d": self.args_template_d,
|
||||
"cookies": self.cookies,
|
||||
"openid": self.openid,
|
||||
"openkey": self.openkey,
|
||||
"source": self.source,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, d: dict) -> "SessionState":
|
||||
return cls(
|
||||
xmidas_ops=list(d.get("xmidas_ops", [])),
|
||||
key16=list(d.get("key16", [])),
|
||||
key1=list(d.get("key1", [])),
|
||||
xmidas_token=d.get("xmidas_token", DEFAULT_XMIDAS_TOKEN),
|
||||
args_template_d=d.get("args_template_d", ""),
|
||||
cookies=dict(d.get("cookies", {})),
|
||||
openid=d.get("openid", ""),
|
||||
openkey=d.get("openkey", ""),
|
||||
source=d.get("source", ""),
|
||||
)
|
||||
|
||||
|
||||
def load_session(path: str | Path) -> SessionState:
|
||||
"""从 JSON 加载会话态并校验。"""
|
||||
p = Path(path)
|
||||
if not p.exists():
|
||||
raise FileNotFoundError(f"会话态文件不存在: {p}")
|
||||
st = SessionState.from_json(json.loads(p.read_text(encoding="utf-8")))
|
||||
errs = st.validate()
|
||||
if errs:
|
||||
raise ValueError("会话态校验失败:\n " + "\n ".join(errs))
|
||||
return st
|
||||
Reference in New Issue
Block a user