Files
live-hub-py/docs/HUYA_CHAT_缺失字段补齐方案.md
T

12 KiB
Raw Blame History

虎牙网页 Cookie 缺失字段补齐方案(历史记录,2026-09-01 晚)

当前字段状态以 HUYA_COOKIE路线状态.md 为准;本文保留当晚的抓包与联调过程。

目标:账号 19507362959(DB id=58,yyuid=1199664135026)跑通精英宝典 WSS query_game_name(checkUserBindGameAccount)/ query_points(getUserScore)。 当前账号 cookie 仅 16 字段(登录凭据),对比 9.1 抓包 42 字段缺 26 个。 本文档按"浏览器实测来源 → 生成方案"逐字段确定,重点分析 4 个核心设备字段。

一、背景结论(已有证据)

  • 9.1 抓包(2026-09-01 09:36)42 字段 cookie:guid/game_did/_qimei_uuid42/udb_* 等全部齐全, 上午所有业务接口成功;当天 21:40 用同一 cookie 逐字节重放,带 cookie 的业务接口全部返回 905/259,不带 cookie 的 getActInfo/getActTaskDetail 仍成功 → 905 是 udb 登录态过期, 不是请求帧格式问题(重放原字节即可复现)。
  • 浏览器实测(真实 Chrome CDP,evidence/browser_cookie_harvest/report.md): 7 个必填网页设备字段全部由页面脚本写 document.cookie 或服务端匿名接口下发产生:
    字段 产生机制 协议可否复刻
    udb_deviceid middle/anonymousLogin Set-Cookie(10 年) ✅ 已接入 anon_device
    udb_anobiztoken anonymousLogin 响应 biztoken ✅ 已接入 anon_device
    udb_anouid anonymousLogin 响应 uid ✅ 已接入 anon_device
    udb_guiddata middle URL 第三段 hex32(客户端自选) ✅ 已接入 anon_device
    guid HyUDBWebSDK-Exchange-2.4.js 写 document.cookie 会话值已接入;回退生成规则待确认
    _qimei_uuid42 QIMEI SDK 脚本写 document.cookie 0.6.3 时间/CRC32/随机半字节算法已复刻
    __yamid_new 门户业务脚本写 document.cookie room_normal.js generate32 已复刻
    game_did 门户业务脚本写 document.cookie 35 位、63 字符集规则已复刻

二、账号 58 现状(16 字段)

udb_passport, username, udb_cred, udb_uid, yyuid, udb_biztoken, udb_version, udb_origin, udb_status, sdid, hdid, udb_anouid, udb_anobiztoken, udb_deviceid, udb_appid, udb_guiddata —— 4 个匿名设备字段已有(anon_device 协议), 缺 guid/game_did/_qimei_uuid42/__yamid_new 4 个核心 + 22 个统计字段。

三、缺失字段补齐方案(逐字段)

3.1 四个核心设备字段(本轮重点分析)

字段 9.1 值形态 浏览器首次出现 补齐方案
guid 32 hex,0a7d… 前缀 udbres.huya.com SDK 脚本 wsLaunch 会话值已接入;回退规则待确认
game_did 35 位字母数字 liveapi.ip/getIpLocation 后门户脚本 35 位、63 字符集已复刻
_qimei_uuid42 42 hex,时间前缀 QIMEI SDK 脚本 14 位时间前缀 + CRC32 替换段 + 随机半字节
__yamid_new 32 hex 大写 门户脚本 generate32 已复刻并通过 WSS 验证

浏览器 round1 同一字段多次出现均值稳定(跨 profile 稳定):_qimei_fingerprint 恒为 2822a43b5a3bd016fc844218c35c8a74,_qimei_uuid42 按秒内时间前缀稳定, guid 前缀恒为 0a7dfaa2…。QIMEI 时间/CRC32/随机半字节生成算法已由 SDK VM 固定输入探针闭合,随机字段仍会在每次生成时变化。

3.2 统计/会话字段(随机即可,服务端仅记录)

字段 生成规则 9.1 样例
SoundValue 固定 0.50 0.50
alphaValue 固定 0.80 0.80
isInLiveRoom 固定 true true
__yasmid / __yamid_tt1 17 位随机小数,两者同值 0.24859634691671784
udb_passdata 固定 3 3
_rep_cnt / rep_cnt 随机 0-9 5 / 7
udb_accdata 固定 undefined undefined
h_unt 当前时间戳(秒) 1788226396
__yaoldyyuid = yyuid 1199666914671
_yasids __rootsid%3D+32hex 大写 __rootsid%3DCBCC34C4…
Hm_lvt_5170… 当前时间戳 1788226384
Hm_lpvt_5170… 当前时间戳 1788226571
HMACCOUNT 16 hex 随机(百度统计下发) 1B08C0532E777923
huya_flash_rep_cnt 随机整数 136
huyasp_rep_cnt 随机整数 9
huya_hd_rep_cnt 随机整数 22
huya_web_rep_cnt 随机整数 507

3.3 已有字段(保持真实值)

udb_cred/biztoken/uid/yyuid/passport/version/origin/status/appid/username(登录凭据)、 sdid/hdid(设备指纹)、udb_deviceid/udb_guiddata/udb_anobiztoken/udb_anouid(anon_device)、 huya_ua(normalize 注入)。

五、实现与端到端验证(2026-09-01 晚)

实现(commit 5dc7365):

  • 新增 core/huya/web_cookie_fields.py:fill_web_cookie_fields(cookie, guid, uid) 补齐 4 核心(guid 用 wsLaunch 会话值,_qimei_uuid42/__yamid_new/game_did 随机对齐格式)+ qimei 皮肤 + 22 个统计/会话字段;missing_web_cookie_fields 返回缺失集合。
  • core/huya/elite_session.py:活动通道初始化时若缺网页字段,先 wsLaunch 预取 服务端认可的会话 guid → 补齐 cookie → 重建会话;业务 RPC 统一走补齐后的 cookie(_resolve_cookie)。

端到端结果(账号 id=58,yyyyuid=1199664135026,原始 16 字段登录态):

任务 结果
query_game_name(b_act_id=9271) success,角色=收麦季(手Q/苹果iOS),game_name=和平精英,已绑定(QQ 昵称"羊"),change_bind_day=7
query_points(sid=2203) success,msg=请求成功,gainScore=4880 / usedScore=4880 / available=0

修复前同类任务全部报"接口无响应"(getConfig 超时);修复后 Web API (POST /api/huya/tasks/batch,账号 58)两条任务均 success 落库。

复现命令:

cd /Users/yml/codes/live-hub-py
.venv/bin/python /tmp/huya_test_session.py   # 原始 DB cookie → 自动补齐 → 查角色/积分
./dev.sh                                     # 界面 http://localhost:5174 → 精英宝典

六、风险与验证要求

当前实现已经通过活动 WSS 查询链路验证。guid 的回退值和设备字段持久化仍需继续完善;详细状态见 HUYA_COOKIE路线状态.md。

不同通道对网页设备态字段的依赖不同,补齐策略按通道区别:

通道 代表接口 Cookie 使用方式 原始 16 字段能否工作
活动 WSS(mobileui/webActUI) getConfig / getUserScore / checkUserBindGameAccount / scoreExchangePrize AUTH 帧 + 业务 tReq 均带完整 cookie,wsLaunch 会话 guid 需回写 ❌ 缺 4 核心字段时 getConfig 超时;需补齐(已接入 elite_session)
商城 WSS(shopMiddleUI,m-shop.yaoguo.com) getGoodsInfoV5 / createOrderV5 / payOrderSubmit 业务 tReq UserId.sCookie 带完整 cookie,sGuid 置空(HAR 实证) ✅ 实测原始 cookie 正常响应(403 只是业务参数校验)
HTTP RPC(cdnws.api.huya.com POST) query_user_score / get_act_prize_list / build_bind_urls / get_livelink_mini_qrcode baseinfo + 业务 tReq 带完整 cookie,_resolve_cookie_guid 自动用 guid→udb_guiddata→sha256 派生 ✅ 实测原始 cookie 直接返回 status=200(积分 4880)

要点:

  1. 活动 WSS 是唯一强校验网页设备态的通道:AUTH/getConfig 前置就失败(无响应), 补齐字段后成功(commit 5dc7365)。
  2. 商城 WSS 不校验:UserId.sGuid="" 且 cookie 原样发送,服务端接受原始登录态 (实测 getGoodsInfoV5 返回业务 403 而非连接/解析错误)。
  3. HTTP RPC 自带 guid 派生:缺 guid 时依次用 udb_guiddata[:32]、yyuid|udb_uid| udb_passport|username|udb_biztoken 的 sha256 派生,业务请求体可带原始 cookie 直接成功 —— 这是「活动接口当前主要依赖核心认证字段」的佐证(与 HUYA_COOKIE合并审计与来源矩阵.md 结论一致)。
  4. 因此没有其他必须补齐的 cookie 字段:活动 WSS 之外,商城 WSS 与 HTTP RPC 用 原始登录态即可跑通。剩余未实测的链路(商城下单/支付等)依赖的仍是同一份 原始 cookie + udb_cred/biztoken 登录态,不涉及网页设备字段的新增要求。

八、商品/兑换全链路验证(2026-09-01 晚,活动 WSS)

补齐会话后逐接口实测(账号 58,sid=2203):

接口 请求参数 响应
getActPrizeList sid=2203 status=200,29 个商品 / 2 分类(限量返场/精英专享),如 pid=13161 破片手榴弹 3600 分
getActPrizeDetail sid=2203, pid=13161 status=200,详情正常(score=3600、频次 600/3、时段 00:00-23:59:59、可兑)
getUserPrizeRecords sid=2203 status=200,历史 2 条(赤蝎幽灵 3600 / 萌神柯基 1280,已发放)
scoreExchangePrize sid=2203, pid=13161 status=604"兑换货币不足" —— 协议往返成功,业务侧拒绝(账号可用积分 0)

结论:商品刷新/选择/兑换接口与 9.1 抓包字节逐一对齐(sid/pid/ip/clientEnv/source/ isRole),RPC 往返全部正常;604 是账号真实积分状态(历史兑换已用 4880/4880), 非协议问题。兑换成功路径需账号有可用积分后复测;发起兑换前 query_user_score 的 available_score 先行校验可避免 604。

  1. guid/_qimei_uuid42/__yamid_new/game_did 的真实性/关联性服务端是否校验未知; 必须用生成值跑通线上活动 WSS 全链路才能定论,不能只过长度测试。
  2. 统计字段随机值不影响接口语义,但顺序建议与 9.1 cookie 保持一致以便对照。
  3. 补齐后仍需新鲜的 udb 登录态(905 = 过期),登录链路见 app_login.py。

九、浏览器注入 ck 未登录的根因(2026-09-01 晚实测确认)

现象:把 App 扫码登录产出的 41 字段网页 ck 注入浏览器,打开 www.huya.com 顶部仍显示 "登录"按钮(未登录)。

排查过程(CDP 有头 Chrome 实测):

  1. ck 本身有效:curl 带该 ck 请求 l.huya.com/udb_web/udbport2.php?m=HuyaLogin&do=checkLogin 返回 {"isLogined":true,"userName":"hy_300539756","uid":"1199667330433",...}; 8.31 真实扫码登录抓包的 checkLogin 成功值与 verify data:null 均一致。 注意:user.huya.com/liveHttpUI/checkUserTimeIsLogin 的 iIsLogin:0 不判定 登录态 —— 真实网页 ck 抓包同样为 0,可排除。
  2. web/cookie/verify 的 data:null 也是正常成功形态,非未登录信号。
  3. document.cookie 检查发现:注入后页面里只有设备字段(guid 等)、没有 udb_uid/udb_cred/udb_biztoken/yyuid —— 登录凭据没有被 www.huya.com 子域携带。

根因:Network.setCookie 的 domain 参数不能写 huya.com,必须写 .huya.com (带前导点)。

  • domain="huya.com"(无前导点)→ Chrome 存为 host-only cookie,只有精确访问 huya.com 时才发送;www.huya.com / l.huya.com / udblgn.huya.com / user.huya.com 等所有子域都不会携带 → 页面意义上的登录判定失败。
  • domain=".huya.com"(带前导点)→ 存为 domain cookie,huya.com 及其全部子域 都携带。实测注入后 document.cookie 含全部字段,顶部导航"登录"按钮消失、 出现登录用户专属项(如"关注")。

正确注入姿势(CDP):

{"method":"Network.setCookie","params":{
  "name":"udb_uid","value":"1199667330433","domain":".huya.com",
  "path":"/","secure":false,"httpOnly":false}}

手工用浏览器插件/DevTools 注入时同样注意:Domain 填 .huya.com(用户输入时 Chrome 会规范化为前导点形式;若插件按 host-only 保存则无效)。HttpOnly 无需设置 —— uzb_* 登录凭据在真实网页中可由脚本读取,非 HttpOnly。