Skip to content

fix(189pc): 更新天翼云盘PC协议版本,修复扫码卡死,支持账密登录时的验证码二次验证 - #3105

Open
naiyQAQ wants to merge 1 commit into
OpenListTeam:mainfrom
naiyQAQ:fix/189pc-login
Open

naiyQAQ wants to merge 1 commit into
OpenListTeam:mainfrom
naiyQAQ:fix/189pc-login

Conversation

@naiyQAQ

@naiyQAQ naiyQAQ commented Sep 20, 2026

Copy link
Copy Markdown

Summary / 摘要

修复 189CloudPC 驱动无法登录的问题,并把协议参数对齐到官方 PC 端当前版本。

问题现象:

  • 扫码登录:手机扫码后能弹出授权、点确认也成功,但存储管理页面始终停在二维码页,不进行下一步,点刷新也没反应。
  • 只填 token:保存后立即报 res_code: InvalidArgument, res_msg: params is null
  • 账密登录:提示「设备ID不存在,需要二次设备校验」后无法继续,驱动没有实现二次校验流程。

根本原因:

驱动使用的 appId8025431004,而官方 PC 端(cloud.189.cn 网页/客户端)已改用 9317140619。天翼云盘的 token、session 和二维码会话都与 appId 绑定,所以:

  • 二维码在 9317140619 下生成,驱动却拿 8025431004 去轮询领授权结果 → 服务端认为不是同一个会话 → 永远查不到 status: 0 → 页面卡死;
  • 用户从官方客户端抓到的 accessToken9317140619 签发的,驱动拿 8025431004getSessionForPC.action 换 session → 换不回 sessionSecret → 后续请求算不出 params → 报 params is null

已用 curl 对真实接口验证:同一个 token 配 appId=9317140619 可以正常换出 sessionKey/sessionSecret

用户可感知的变化 / User-visible changes

  • 扫码登录可以正常完成,且改为本地轮询:扫码确认后自动进入下一步,不再需要反复点保存。
  • 账密登录遇到设备二次校验时,会发送短信验证码并提示填写;填入新增的 sms_code 字段后再次保存即可完成登录。
  • 校验通过后服务端下发的 DEVICEID 会被保存下来,后续登录不再重复触发二次校验(官方有效期 120 天)。
  • username / password 不再是必填项:只填 access_tokenrefresh_token 即可保存存储,不需要再填占位符。
  • token 刷新失败时会报出真实原因(如 refreshToken为空刷新失败),不再一律显示成误导性的 params is null
  • 登录页结构变化时返回带字段名的错误提示,不再 panic。

重要实现变化 / Implementation changes

  • APP_ID 改为 9317140619VERSION 改为 7.2.4.0。新增 QR_CLIENT_TYPE = "1" 仅用于扫码状态轮询;密码登录仍保持 clientType=10020(已通过抓包确认这里本来就是对的)。
  • 扫码轮询补齐官方客户端实际发送的参数:cb_SaveName=3isOauth2=falsestate,以及 user-finger 请求头和真实的 logbox Referer。轮询改为本地循环(2 秒一次,最多 20 秒),超时后把二维码交回前端,避免长连接被反向代理掐断。
  • 登录页参数解析:当前登录页把 lt/reqId 放在跳转地址上,paramId 需另外向 appConf.do 获取;旧版把三者写在页内变量里的格式仍然兼容。appConf.doresult 字段可能是数字也可能是字符串,两种都处理。
  • 设备二次校验result: -133):实现 sendSmsCodeForSecondAuth.dosubmitForSecondAuth.do。该接口没有独立的短信码字段——短信码要放进 epd,用登录时 encryptConf.do 下发的同一个公钥加密(登录时 epd 装的是密码)。整个流程复用同一套 paramId 和 cookie 会话,中途不重新初始化。
  • refreshToken.do 失败检测:该接口刷新失败时返回 HTTP 200 加 {"result":-36,...},而 resty 的 SetError 只在 4xx/5xx 触发,RespErr 里也没有 result 字段。原先失败被当成成功,access token 被清空后继续去换 session,最终暴露成误导性的 params is null。新增 RefreshTokenResp 单独判断。
  • getSessionForPC.action 的三处调用合并为 getSessionByRedirectURL,统一补上 returnType=JSONX-Request-ID

配置变化 / Config changes

Addition 新增 5 个可选字段,均向后兼容,老配置无需修改:

字段 说明
sms_code 设备二次校验的短信验证码,提示时填入并再次保存
device_id 二次校验通过后服务端下发的 DEVICEID,保留可避免重复校验
client_sn 设备序列号,从官方客户端抓到才填,留空则不发送
jg_open_id 官方客户端上报的推送 ID,可选
user_finger 设备指纹,留空则自动生成并保存

username / password 由必填改为可选。

关于设备标识的说明:client_snjg_open_id 只在用户明确填写后才发送。虽然抓包里官方请求带着这两个值,但经 curl 验证,不带它们同样能成功换出 session;而把某个账号的设备序列号写死进驱动,会让所有用户上报同一个服务端并不认识的设备号,因此改为可选。user_finger 每个存储随机生成一次并持久化,保证服务端看到的是稳定的同一台设备。

  • This PR has breaking changes.
    / 此 PR 包含破坏性变更。
  • This PR changes public API, config, storage format, or migration behavior.
    / 此 PR 修改了公开 API、配置、存储格式或迁移行为。
  • This PR requires corresponding changes in related repositories.
    / 此 PR 需要关联仓库同步修改。

说明:仅为 189CloudPC 驱动新增可选配置字段,并把 username/password 由必填改为可选。纯增量变更,现有配置无需迁移,也不影响其它驱动。

Related repository PRs / 关联仓库 PR:

  • OpenList-Frontend: none
  • OpenList-Docs: none

Related Issues / 关联 Issue

Testing / 测试

平台: Windows 11 (amd64),Go 1.27.1

手动验证(真实天翼云盘账号,挂抓包代理逐个请求核对):

  • 扫码登录 —— 二维码正常生成,内容为 qrClinentLogin.do?paras=new_uuid=...|9317140619;手机扫码确认后自动完成登录并挂载成功。
  • 扫码轮询 —— 服务端返回 -106(未扫描)而非报错,证明参数被接受;本地轮询跑满时间窗口后正确把二维码交回前端。
  • 账密登录 + 设备二次校验 —— 触发 -133 后成功收到短信,填入 sms_code 再次保存后校验通过并完成登录。
  • 只填 token 保存 —— 不填用户名密码可以正常保存存储(原先被必填校验拦住)。
  • 错误路径 —— 无效 token / 无效 refresh token / 什么都不填,三种情况均返回指向真实原因的报错,不再是 params is null

接口层验证(curl 直连真实接口):

  • 同一 token 配 appId=9317140619 可换出 sessionKey/sessionSecretres_code: 0)。
  • refreshToken.do 失败时确认返回 HTTP 200 + result 字段,印证 SetError 检测不到。
  • content-length 验算 submitForSecondAuth.do 抓包的字段组合,确认该接口没有独立短信码字段。
  • 用服务端真实公钥验证 epd 加密结果格式为 {NRP} + 256 位 hex,与抓包一致(临时测试,未提交进仓库)。

命令:

  • go test ./...
  • go build ./... —— 通过
  • go vet ./drivers/189pc/ —— 通过
  • go test ./drivers/189pc/ —— 通过
  • GitHub Actions Test Build —— 7/7 平台全部成功(darwin-amd64/arm64、windows-amd64/arm64、linux-amd64/arm64-musl、android-arm64)

关于 go test ./...:本仓库 main 分支当前有 20 个包测试失败(多数为 non-constant format string 的 vet 报错导致 build failed,分布在 drivers/123drivers/189drivers/chaoxingdrivers/google_drivedrivers/google_photodrivers/lanzouinternal/net 等),均为既有问题,与本 PR 无关。

本 PR 使该数字从 20 降到 17drivers/189pc 原有两处 fmt.Errorf 非常量格式串问题在本次重构中被顺带修掉,该包现已通过测试。未去修其它包的既有问题,以保持本 PR 聚焦。

Checklist / 检查清单

  • I have read CONTRIBUTING.
    / 我已阅读 CONTRIBUTING
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
    / 我确认此贡献符合仓库许可证、贡献规范和行为准则。
  • I have formatted the changed code with gofmt, go fmt, or prettier where applicable.
    / 我已按适用情况使用 gofmtgo fmtprettier 格式化变更代码。
  • I have requested review from relevant maintainers or code owners where applicable.
    / 我已在适用情况下请求相关维护者或代码所有者审查。

gofmt 说明:drivers/189pc/utils.gogetFiles 函数(约 210–243 行)存在既有的缩进不规范,属本 PR 未触及的代码,为减小 diff 未一并调整。本 PR 新增及修改的代码均符合 gofmt

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.
    / 此 PR 包含 AI 辅助内容。

Tools used / 使用工具:

  • ChatGPT
  • Codex
  • GitHub Copilot
  • Claude
  • Gemini
  • Other (please specify) / 其他(请注明):

Usage scope / 使用范围:

  • Code generation / 代码生成

  • Refactoring / 重构

  • Documentation / 文档

  • Tests / 测试

  • Translation / 翻译

  • Review assistance / 审查辅助

  • I have reviewed and validated all AI-assisted content included in this PR.
    / 我已审核并验证此 PR 中的所有 AI 辅助内容。

  • I have ensured that all AI-assisted commits include Co-Authored-By attribution.
    / 我已确保所有 AI 辅助提交都包含 Co-Authored-By 归属信息。

  • I can reproduce all AI-assisted content included in this PR without any AI tools.
    / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。

QR code scans were authorized on the phone but the storage stayed stuck on
the QR page, and token-only setups failed with "params is null".

The driver used appId 8025431004 while the official PC client uses
9317140619. Tokens, sessions and QR sessions are all scoped to an appId, so
the mismatch meant the QR poll never saw status:0 and an accessToken could
not be exchanged for a sessionSecret.

- Use appId 9317140619 and version 7.2.4.0. QR state polling uses
  clientType=1; password login keeps 10020.
- Send the QR poll parameters the official client sends (cb_SaveName,
  isOauth2, state, user-finger header, logbox Referer) and poll locally
  instead of only checking once per save.
- Parse lt/reqId from the logbox redirect and paramId from appConf.do. The
  new login page no longer embeds them as inline variables; the old inline
  format is still supported.
- Implement the -133 second device verification via
  sendSmsCodeForSecondAuth/submitForSecondAuth. That endpoint has no
  dedicated SMS field: the code goes into epd, encrypted with the same
  public key used for the password. Persist the DEVICEID cookie so the
  verification only happens once.
- Detect refreshToken.do failures. It reports them as HTTP 200 with a
  result field, so SetError never fired and a failed refresh was treated as
  success, surfacing later as a misleading "params is null".
- username/password are no longer required, so token-only storages save
  without placeholders. clientSn/jgOpenId are optional and only sent when
  configured; user-finger is generated once per storage.
- Return named errors instead of panicking when the login page changes shape.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@pikachuren pikachuren left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 感谢 @naiyQAQ 提交!
🤖 AI 自动审核声明:本评审报告由 AI 自动生成,当前使用 Claude Opus 5 模型进行分析。
⚠️ AI 分析结果仅供参考,可能存在误判或遗漏。如您发现任何问题或有不同意见,欢迎随时提出讨论和纠正。
⚠️ 重要提醒:即使 AI 评审认为代码质量良好且建议合并,最终是否合并仍需由项目维护者进行人工判定。项目维护者会综合考虑代码质量、项目规划、技术方向、团队资源等多方面因素做出是否合并的决策。

🎯 结论

✅ Approve — 代码质量良好,建议合并

📖 概要

fix(189pc): 更新天翼云盘PC协议版本,修复扫码卡死,支持账密登录时的验证码二次验证

📊 评审结果

改动合理,无重大问题发现。代码逻辑清晰,符合项目规范。

🎯 结论:✅ Approve — 建议合并

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants