Files
cpdaily_xiaozhushou/backed
becomer 458e13b807
ci/woodpecker/tag/build Pipeline was successful
CAS 回调遇「参数解码错误」自动重取盐重试,覆盖 DK 轮换窗口
多个无凭证实验已确认:
- /api/sec_js 的 DK 盐每次请求都不同,且与会话无关(同 cookie 两次也不同);
- 服务端只能从密文里还原 DK,不依赖任何会话状态;
- 用当次 sec_js 加密的密文,服务端必定能解开(返回「用户名或密码错误」而非解码错误);
- 无/无效 CASTGC 时 CAS 直接返回 200+登录页(Set-Cookie 清除 CASTGC),
  根本不会给出 ticket——所以「参数解码错误」发生时 ticket 是有效的,
  失败只可能发生在 /cas/callback 的解密环节。

由此推论:取盐与提交之间若服务端轮换了 DK,就会解密失败。
官方前端对该错误的提示正是「刷新页面后尝试」,说明官方也视其为可重试的
瞬时问题,而非致命错误。

改动:
- 新增 isXsgzDecodeError:仅当响应体含「参数解码错误」时为真
  (凭证错误、ticket 无效等不触发重试);
- 命中时重新拉取 sec_js、重新加密、重新提交一次。

安全性:解码失败意味着服务端没解出内容,ticket 未被消费,
因此重试不会浪费这张一次性 ticket。

日志:重试时记录 dkChanged(两次盐是否不同),
可据此确认线上是否真的发生了轮换,为后续是否加重试次数提供依据。
2026-10-18 17:18:14 +08:00
..
v1.2.50:辽宁工程技术大学(lntu)登录适配——强制走 CAS + 滑块验证码——① 根因:平台接口返回 joinType=CLOUD(IsIap=true),但网关 /iap/doLogin 不存在(HTTP 405),IAP 账密提交必然失败并返回 FAIL_UPNOTMATCH("用户名或密码不匹配",误导用户以为密码错误);真实链路为 fdm.lntu.edu.cn/iap 302 → 学校 CAS(authserver.lntu.edu.cn/authserver/login)→ 账密 + 验证码 → 回调 /iap/loginSuccess?sessionToken=...&ticket=... 建立网关会话(cookie 落在 fdm.lntu.edu.cn,与 wec-* 任务接口同域);② 修复:新增 login_lntu.go 的 lntuCasLogin(同 xcu 模式,用 /iap 网关入口覆盖 ampUrl 后走通用 CAS 流程),CpdailyLogin 中对 LntuSchoolId 特判强制走 CAS;③ 验证码类型:抓取登录页 JS 确认 captchaSwitch="2" 且 startLogin 走 createSliderCaptcha()(wisedu 定制滑块,非图形验证码),协议与华侨大学完全同源(openSliderCaptcha.htl 取图、sign=AES(JSON.stringify({canvasLength,moveLength,tracks}), 小图 base64 末16字节) 提交 verifySliderCaptcha.htl、errorCode==1 通过),故仅需将 lntu 加入 sliderIds 配置即可复用现有滑块实现(config.toml.example 同步更新);④ 端到端实测:真实待适配账号两次登录均一次通过(gapX=92/149 首候选 offset=0 直接命中 errorCode=1),CAS 302 → 6 cookies(CASTGC/JSESSIONID/MOD_AUTH_CAS/happyVoyage/route/platformMultilingual)→ FetchUserProfile 会话有效;⑤ 按用户要求回滚此前 LoginUrl(忘记密码地址)改动——原地址打不开是因为走了 IAP 入口,改走 CAS 后浏览器可直接打开,无需特殊处理;⑥ 新增 login_lntu_test.go(入口计算 7 用例 + ampUrl 覆盖 + 协议常量),go test ./...、go vet 全过
2026-09-14 23:12:06 +08:00