CHAPTER 0 · 缘起

TGC 到底绑不绑定设备?
—— 一次控制变量法

前一天把 algorithm-cli 的登录态收进独立 Chrome Profile 后,冒出一个诱人的想法:能不能把 IdP 签发的 TGC 搬到一个全新的浏览器 context 里复用,省掉每次都启动那个笨重的有头浏览器?结果——搬过去就不工作了。这份报告记录我们如何用控制变量法定位到真正的原因:CAS 在校验 TGC 时至少绑定了 User-Agent

🎫

TGC 不是纯凭据

它像一张登记了设备描述的门票,只拿门票、描述对不上,CAS 就要求重新登录
🔬

控制变量法

固定 TGC / service / 重定向,只改 User-Agent,观察 CAS 是否仍认可这枚 TGC
⚠️

结论有边界

只证明 UA 影响校验,不排除 IP / 设备指纹;不可外推到"只校验 UA"
🛠️

工程取舍

不搬运 TGC,始终在签发 profile 内完成 CAS 导航,改走 CDP 原生 harvest
怎么用这份指南实验 A、B 都带 播放控件(⏮ ◀ ▶ ⏭ ↻)。建议一步步点 ▶看请求如何流动,详情面板会同步显示该步的 HTTP 方法、URL、请求头(尤其 User-AgentCookie)与注释。两个实验只差一个 UA,对照着看最清楚。

一句话理解这次实验

前一天已经确认:TGC(Ticket Granting Cookie)是 IdP 域上的 SSO 会话凭据,ST(Service Ticket)是 IdP 给某个业务系统签发的一次性票据。问题是:TGC 到底是不是"一颗 cookie 走天下"?如果它在任意浏览器里都能换出 ST,那我们就能把它抽出来复用;如果不行,那它必然还绑定了签发时的某些请求特征。本实验就是来回答"TGC 绑不绑定、绑定什么"。

先建立心智模型把 TGC 想成一张电影票:票本身是真的,但检票口可能还核对购票时登记的身份特征。本实验要查的就是:检票口(CAS)到底核不核对、核对哪一项。
TGC = 门票 —— 证明"用户已在 IdP 登录"。
User-Agent = 门票登记的设备描述 —— 签发 TGC 时浏览器自报的家门。
控制变量 —— 只动 UA、其余全固定,看检票结果是否翻转。
CHAPTER 1 · 方法

控制变量法:只动 UA,其余全锁死

要判断"TGC 是否绑定 UA",最干净的办法是控制变量:把所有可能影响 CAS 校验的因素都固定下来,只翻转 User-Agent 一个变量,观察结果是否随之翻转。如果结果翻转,就说明 UA 确实影响校验;如果不变,则 UA 至少不是决定性因素。

固定不变的量控制变量

  • 同一枚 TGC:LogosCowork 登录后签发,全程不重新登录、不刷新。
  • 同一目标 service:访问同一个受 CAS 保护的内部业务系统。
  • 同一重定向地址service= 参数指向同一个回调 URL。
  • 全新的浏览器 context:每次都用干净 cookie jar,只放入这枚 TGC。

唯一翻转的量自变量

  • User-Agent:实验 A 用 Chrome/150(与签发时不一致)。
  • User-Agent:实验 B 用 Chrome/130(与 LogosCowork 签发时一致)。
  • 其余请求头、cookie、目标地址、重定向参数全部相同
因变量:CAS 是否签发 ST(= TGC 是否被认可)。
为什么用"全新 context"关键在于排除浏览器侧的状态干扰:如果直接在签发 TGC 的那个 profile 里访问,profile 里可能还残留其它 cookie / 缓存 / 会话,无法判断到底是 TGC 起的作用还是别的。放进一个只有这枚 TGC 的干净 context,再只翻转 UA,因果关系才干净。

判断标准

结果CAS 的行为说明
认可识别 TGC 有效 → 签发 ST → 302 回业务系统TGC 在该 UA 下可用
不认可不签发 ST → 返回登录页(200)TGC 在该 UA 下不可用

两个实验的 UA 只差一个版本号。如果 A 被拒、B 通过,且其余变量全同,则"UA 是否一致"是唯一能解释结果翻转的因素。

CHAPTER 2 · 实验 A

UA 不一致 → CAS 拒绝签发 ST

把 LogosCowork 签发的 TGC 放进全新 context,只把 User-Agent 改成 Chrome/150(与签发时的 Chrome/130 不一致),然后访问受保护的业务系统。点 ▶ 看完整链路。

实验 A 结果:被拒CAS 收到了 TGC,但因为 User-Agent 与签发时不一致,没有签发 ST,直接返回登录页。TGC 在这个 UA 下不可用。注意:被拒不是 401 / 403,而是返回登录页——CAS 的态度是"我不认识这枚 TGC 的持有环境,请你重新登录"。
CHAPTER 3 · 实验 B

UA 一致 → CAS 立即签发 ST

同一枚 TGC、同一个全新 context、同一个 service、同一个重定向地址,唯一区别是把 User-Agent 改回 Chrome/130(和 LogosCowork 签发时一致)。点 ▶ 看链路如何一路走通。

实验 B 结果:通过同样一枚 TGC、同样一个干净 context,只因为 UA 改回了 Chrome/130,CAS 立即签发 ST,业务系统验证 ST 后建立本地 session,登录成功。

对照:A 与 B 只差一个变量

变量实验 A实验 B
TGC同一枚(LogosCowork 签发)
目标 service同一个
重定向地址同一个
浏览器 context全新、仅含该 TGC
User-AgentChrome/150Chrome/130
CAS 是否签发 ST否 · 返回登录页是 · 签发 ST
CHAPTER 4 · 结论

TGC ≈ 门票,UA ≈ 登记的设备描述

结果翻转了:唯一变量是 UA,A 被拒、B 通过。所以可以下结论——

可证明的结论CAS(本例中的 Temu 内部 CAS 实现)在校验 TGC 时,至少会把 User-Agent 纳入校验。只拿 TGC 但 UA 与签发时不一致,CAS 不认可,要求重新登录。可以把它理解成:TGC = 门票,UA = 门票登记的设备描述

但严谨地说,结论有边界

✅ 能说的

  • "UA 是否一致"会影响这枚 TGC 能否被使用。
  • 本实验的单一 CAS 实现上,UA 是一个被校验的因子。
  • 搬运 TGC 到 UA 不同的环境是不可靠的复用方式。

❌ 不能说的

  • 不能说"CAS 校验 UA"。它可能还校验 IP、设备指纹或其它特征。
  • 不能外推到别的 CAS 实现——这是 Temu 内部实现的行为,非协议要求。
  • 不能断言"UA 一致就一定通过"——还可能有其它未被控制的因子。

控制变量法能证明"某因子有影响",但无法穷举"还有哪些因子也有影响"。这是单次实验固有的边界,也是下一章"三层事实"要区分清楚的重点。

CHAPTER 5 · 落地

不搬运 TGC,在签发 profile 内完成 CAS 导航

既然 TGC 绑定签发时的环境特征(至少含 UA),最稳妥的做法不是把 TGC 抽出来到处搬,而是始终在签发它的那个专用 Chrome profile 内完成后续 CAS 导航——这样 UA、环境特征天然一致,CAS 会顺畅地用 TGC 换出 ST。

这直接决定了 algorithm-cli 的改造方向放弃"启动一个有头 Chrome 等用户登录、再把 cookie 读出来塞进业务请求"的旧链路,改为通过 CDP 连接 LogosCowork 已有的渲染页面,直接调用 window.cowork.mcp.harvestCookies("sre.temu.team/event") 取业务 Cookie。TGC 始终留在签发它的 profile 里,由那个环境自己完成 CAS 换 ST、换业务 session,我们只拿最终的业务会话 Cookie(如 baizeSessionId)。

改造要点

维度旧方案新方案(原生 harvest)
Cookie 来源读 9278 ChromeDebug Profile / page.cookies()CDP 连 9277 主渲染页,执行 harvestCookies()
TGC 归属尝试把登录态抽离到独立 contextTGC 留在签发 profile,由其完成 CAS 导航
缓存与失效每次开可见页面刷新内存缓存;401 / 403 强制重 harvest,只重试一次
回退路径保留 algo login / 9278 / ChromeDebug删尽回退,只留一条 harvest 链路
用户感知常弹可见 Chrome 窗口、抢焦点无头、不开窗口、不打断
顺带打通的同一套 harvestCookies 也能取 PAI(tech.temu.team/pai)的登录态,本地 Jupyter Kernel 代理链路因此连通。一份机制,覆盖 SRE 告警与 PAI 两条业务线。
新方案解决不了的问题它减少的是界面干扰与回退复杂度,不是取消认证机制:TGC 自身过期、CAS 要求 MFA / 验证码、用户无权限、服务端真正的业务 403、profile 损坏——这些都仍需人工 algo login 兜底。
CHAPTER 6 · 严谨性

把结论分进三层:公开事实 / 协议事实 / 工程推断

认证这种话题最容易把"协议规定的""某实现做的""我们推测的"搅在一起。为了避免以讹传讹,把本报告涉及的所有结论按依据强度分进三层——哪一层都不要冒充更高层

层级结论依据强度
公开事实 TGC 是 IdP 域上的 SSO 会话凭据;ST 是一次性、绑定 service 的票据,业务系统验证 ST 后建立自己的本地 session CAS 协议规范 + 通用 SSO 常识 高 · 跨实现通用
协议事实 CAS 协议本身不要求 TGC 绑定 User-Agent。"是否绑定 UA / IP / 设备"是各实现的安全策略选择,协议层留白。 CAS 协议规范 高 · 协议层确定
工程推断 本实验观察到 Temu 内部 CAS 实现校验 TGC 时至少纳入 UA;是否还校验 IP / 设备指纹未知。不可外推到其它 CAS 实现。 本次控制变量实验,单一实现 中 · 限定单一实现
为什么要这样分"TGC 绑定 UA"是工程推断,不是协议事实,更不是公开事实。如果把它当成"所有 CAS 都这样"去讲,就会把单一实现的行为误传播成协议特性——这正是前一天复盘时给自己记下的卡点。分层之后,每句话都能追溯到它的依据边界。

给读者的三条带走