fix(huya): 🔒 一号一设备缺口修复 — hydevice 指纹状态按账号隔离

日志证据: 两账号 sdid 前缀相同 (0UnHUgv0_qmfD4KAKlwzh...) — get_huya_sdid
默认用全局临时目录, 所有账号共享同一份 hydevice 设备采集状态 → 服务端可
跨账号关联设备, 违背一号一环境。

- device_fingerprint: 新增 account_state_dir(account) → data/huya_fp_states/<账号>/
  (持久化, 同账号多次登录=同一台'设备')
- app_login 扫码绑定四步流 + login.prepare_device: 传入账号级 state_dir
This commit is contained in:
yml2213
2026-08-29 16:27:35 +08:00
parent d6ab4d8699
commit bf6dee1850
3 changed files with 23 additions and 5 deletions
+5 -2
View File
@@ -36,7 +36,7 @@ from loguru import logger
from .cert_forge import build_p1, decrypt_cert, forge_cert, parse_p1
from .cookie_utils import normalize_huya_cookie
from .device_fingerprint import get_huya_sdid
from .device_fingerprint import account_state_dir, get_huya_sdid
from .device_profile import get_profile
from .dfp_register import DfpRegistrationError, register_device
from .envelope_forge import Envelope
@@ -445,7 +445,10 @@ class HuyaAppPasswordLogin:
# 4) 模拟扫码绑定四步流获取 biztoken
try:
sdid_obj = get_huya_sdid(allow_fallback=True)
# 一号一设备: sdid 状态按账号隔离 (默认全局目录会让所有账号共享
# 同一份 hydevice 设备状态, 服务端可跨账号关联 — 见 R40 缺口修复)
sdid_obj = get_huya_sdid(allow_fallback=True,
state_dir=account_state_dir(self.username))
sdid = sdid_obj.sdid if sdid_obj else ""
pc = QrRole(pc=True, sdid=sdid, proxies=self.proxies)
ph = QrRole(pc=False, sdid=sdid, proxies=self.proxies)
+14 -1
View File
@@ -20,6 +20,17 @@ FINGERPRINT_DIR = Path(__file__).parent / "fingerprint"
RUNNER_JS = FINGERPRINT_DIR / "runner.js"
SDID_PREFIX = "__SDID__"
# 每账号独立的 hydevice localStorage 状态目录 (一号一设备的关键):
# 默认全局临时目录会让所有账号共用同一份设备采集状态 → sdid/40hex hdid 同源,
# 服务端可跨账号关联设备。按账号分目录后, node 链路为每个账号维护独立"设备"。
FP_STATE_ROOT = Path(__file__).resolve().parents[2] / "data" / "huya_fp_states"
def account_state_dir(account: str) -> Path:
"""账号专属指纹状态目录 (持久化, 保证同一账号多次登录是同一台'设备')。"""
safe = "".join(c if c.isalnum() or c in "-_." else "_" for c in (account or "anon"))[:64]
return FP_STATE_ROOT / safe
DEFAULT_TIMEOUT = (8, 40)
@@ -103,7 +114,9 @@ def get_huya_sdid(
Args:
app_id: 虎牙应用 idApp 场景 5008。
state_dir: localStorage 持久化目录(保持设备一致性)None 用临时目录
state_dir: localStorage 持久化目录(保持设备一致性)None 用全局临时目录
(仅单设备场景可用); 多账号请传 account_state_dir(account) 实现
一号一设备 — 同账号多次登录复用同一份设备状态。
allow_fallback: node 失败时是否降级为旧版无指纹方式。
Returns:
HuyaSdidResult(sdid, source, message)source 为 fingerprint/fallback/none。
+4 -2
View File
@@ -226,10 +226,12 @@ class HuyaPasswordLogin:
def prepare_device(self) -> str:
"""获取虎牙风控 sdid(优先 hydevice 高信任指纹,失败降级旧版)。"""
from .device_fingerprint import get_huya_sdid
from .device_fingerprint import account_state_dir, get_huya_sdid
try:
result = get_huya_sdid(app_id="5008", timeout=self.timeout)
# 一号一设备: 每账号独立 hydevice 状态, sdid/40hex hdid 不跨账号同源
result = get_huya_sdid(app_id="5008", timeout=self.timeout,
state_dir=account_state_dir(self.username))
if result.sdid:
self.sdid = result.sdid
self.sdid_source = result.source