- 什么是 CAS 单点登录
- 核心术语一览
- 完整登录流程解析(9 步)
- 关键难点:terminal-jtoken 的来龙去脉
- Python 模拟登录实现
- 常见问题与坑
- 总结
1、什么是 CAS 单点登录
CAS(Central Authentication Service)是由耶鲁大学开发的开源单点登录协议,目前广泛应用于政府、高校、企业等需要多系统统一认证的场景。它的核心思想是:用户只需在认证中心登录一次,即可访问所有接入的业务系统,无需重复输入账号密码。
12333(全国社会保险公共服务平台)正是基于 CAS 协议构建其统一认证体系。用户在 www.12333.gov.cn/cas 完成身份验证后,即可无缝跳转至 si.12333.gov.cn 等各业务子系统。
本文所有分析均基于 Chrome DevTools 抓包观察,目的是理解 CAS 协议原理及其私有扩展机制。请勿将本文内容用于任何违反服务条款的用途。
2、核心术语一览
| 术语 | 全称 | 说明 |
|---|---|---|
| CAS | Central Authentication Service | 耶鲁大学开发的单点登录协议标准 |
| SSO | Single Sign-On | 单点登录,一次认证,全局通行 |
| TGT | Ticket Granting Ticket | 主票据,代表"用户已完成认证",存于服务端 |
| TGC | Ticket Granting Cookie | 存放 TGT 引用的 Cookie,HttpOnly+Secure |
| ST | Service Ticket | 一次性服务票据,用于某个具体业务系统的身份证明 |
| CAS Server | 认证中心 | 本例为 www.12333.gov.cn/cas |
| CAS Client | 业务系统 | 本例为 si.12333.gov.cn |
| terminal-jtoken | --- | 12333 私有扩展,终端身份令牌,非标准 CAS |
3、整登录流程解析(9 步)
下图展示了从打开登录页到最终拿到用户信息的完整链路,涵盖标准 CAS 流程和 12333 私有扩展两个阶段:

整个流程分为两个阶段:

4、关键难点:terminal-jtoken 的来龙去脉
它从哪里来?
步骤③中,业务系统验证 ST 通过后,返回 302 Found,Location 头指向:
python
Location: https://si.12333.gov.cn/osptb/index.html#/login?tQUPMO5EP9P8ZXzzAS0xYv3Zq6Ow0Mc2kvxqnLRG+b72...
# 后面的 /login?加密串 中,加密串解密后得到明文形如 token=xxxxxxx,这个 xxxxxxx 就是 terminal-jtoken 的明文值。

两个 token 的区别
实际请求中存在两个形式不同的 token,容易混淆:

为什么 getCode 不能跳过?
即使已经有了 terminal-jtoken 明文,步骤⑧仍然不能省略。getCode 的真正作用不是"获取 token",而是触发服务端给当前 session 打上"终端已验证"的状态标记 。如果跳过步骤⑧,步骤⑨的 checkAuth 验证 jtoken 时会找不到对应的终端记录,只返回"认证成功"字符串,无法返回用户数据。

5、Python 模拟登录实现
从 Location 提取 terminal-jtoken

6、常见问题与坑

7、总结
12333 的登录体系本质上是 标准 CAS SSO 协议 + 私有终端验证扩展的组合。标准 CAS 部分(步骤①~④)处理身份认证,私有扩展部分(步骤⑤~⑨)建立终端信任关系。
理解这套流程的关键有三点:第一,terminal-jtoken 在步骤③就已经可以获取;第二,步骤⑧的 getCode 是触发终端验证状态的必要前提,不可跳过;第三,请求中同时存在明文 jtoken(header)和加密 jtoken(cookie),两者不可混淆。
从协议设计角度来看,这种"CAS 认证 + 终端令牌"的双层验证机制,在政务系统中相当常见------CAS 解决"你是谁",终端令牌解决"你从哪台设备来",两者共同构成完整的访问控制链路。
本文分析基于网络请求观察,仅用于学习 CAS 协议原理。代码示例中的加密/解密函数需根据实际逆向分析结果自行实现。