资讯动态

主系统登录后,子系统怎么实现自动登录?

发布时间:2026/10/8 6:52:12 来源:尧图企业网站定制
核心回答跨域没法共享 Cookie就靠中央认证中心子系统没登录就跳过去认证中心确认已登录后再跳回来子系统建立自己的登录态。这句话先说到这里就够了。1. 为什么 Cookie 共享解决不了所有 SSO假设主系统 https://www.example.com 订单系统 https://order.example.com 数据看板 https://dashboard.example.com它们属于同一个父域名example.com ├── www.example.com ├── order.example.com └── dashboard.example.com这种情况下可以考虑Set-Cookie: tokenxxx; Domain.example.com浏览器访问order.example.com时就可能自动携带tokenxxx所以同一父域名下可以通过Cookie Domain共享登录态。但如果变成www.example.com order.example.net dashboard.example.org就完全不同了。因为example.com example.net example.org之间不能通过 Cookie 的Domain属性互相共享 Cookie。所以Cookie Domain.example.com不可能让example.net example.org也收到这个 Cookie。2. 跨一级域名怎么办这时候就不能再想着主系统 Cookie ↓ 直接共享 ↓ 子系统而应该变成┌──────────────────┐ │ 中央认证中心 │ │ Auth Server │ └────────┬─────────┘ │ 保存全局登录态 │ ┌──────────────┼──────────────┐ ↓ ↓ ↓ 主系统 订单系统 数据看板 example.com example.net example.org核心思想非常简单不是让不同域名共享 Cookie而是让不同系统共享同一个认证中心。3. 最经典的 SSO 流程例如用户第一次访问https://order.example.net订单系统发现当前没有自己的登录态于是订单系统 ↓ 跳转认证中心 ↓ 认证中心检查自己的登录态假设认证中心发现用户已经登录那么它就不需要用户重新输入账号密码。然后给订单系统一个一次性的认证结果。以经典 CAS 为例这个结果就是ticket完整过程用户 │ │ 访问订单系统 ▼ 订单系统 │ │ 没有本地 Session ▼ 认证中心 │ │ 检查中央 Session │ │ 已登录 ▼ 生成一次性 Ticket │ │ 重定向回订单系统 ▼ 订单系统后端 │ │ 用 Ticket 服务端请求认证中心 ▼ 认证中心 │ │ 校验 Ticket │ │ 返回用户身份 ▼ 订单系统 │ │ 创建自己的 Session ▼ 用户登录成功这里有一个特别重要的点Ticket 不是最终的登录 Token不要简单理解成认证中心 ↓ 把用户 Token 放 URL ↓ 订单系统直接使用经典 CAS 更像认证中心 ↓ 给一个一次性 Ticket ↓ 订单系统后端 ↓ 拿 Ticket 找认证中心兑换用户身份 ↓ 创建自己的 Session所以 Ticket 更接近“这次认证已经成功了你拿着这个凭证来找认证中心确认。”而不是“这是用户以后一直使用的登录 Token。”现代 Web 更常见的是 OAuth 2.0 OIDC子系统 ↓ 跳转认证中心 ↓ 认证中心发现用户已登录 ↓ 返回 Authorization Code ↓ 子系统后端拿 Code 换 Token ↓ OIDC 返回 ID Token / 用户身份 ↓ 子系统建立自己的登录态这里的核心变化是CAS Ticket → 换用户信息 OIDC Authorization Code → 换 ID Token Access Token认证中心到底怎么知道回哪个子系统子系统发起登录时会带上自己的身份和回调地址订单系统 ↓ 认证中心 │ ├── client_idorder └── redirect_urihttps://order.example.com/callbackclient_id告诉认证中心“我是哪个子系统。”redirect_uri告诉认证中心“登录成功后回哪里。”认证中心通常会提前登记order → https://order.example.com/callback dashboard → https://dashboard.example.com/callback所以认证中心不是自己猜而是根据client_id找到对应的回调地址并校验redirect_uri是否匹配。最终完整流程用户访问子系统 │ ▼ 子系统发现没登录 │ │ client_id │ redirect_uri ▼ 认证中心 │ ├── 已登录 ─────────────┐ │ │ └── 未登录 │ ↓ │ 用户登录 │ ↓ │ 建立中央 Session │ └───────┬────────┘ ↓ Ticket / Code ↓ 跳回子系统 ↓ 子系统后端校验 ↓ 获取用户身份 ↓ 建立本地 Session ↓ 自动登录4. 为什么 Ticket 要一次性这是这道题很容易继续追问的地方。假设 URL 是https://order.example.net/callback?ticketST-123456如果这个 Ticket 永久有效就存在明显风险。攻击者拿到ST-123456以后可能再次拿它换取用户身份。所以通常要求Ticket ↓ 只能使用一次 ↓ 认证中心校验成功 ↓ 立即失效于是第一次使用 Ticket → 校验成功 → 返回用户信息 → Ticket 失效 第二次使用 Ticket → 校验失败这就是典型的防重放思路。5. 为什么不直接把 Token 放 URL面试官很可能继续问“那我直接把 Token 放 URL 里不就行了吗”例如https://order.example.net?tokeneyJ...这种方案风险比较大。因为 URL 可能出现在浏览器历史记录 Referer 访问日志 代理日志 监控系统 截图 用户复制分享的链接所以长期有效 Token ↓ 直接放 URL通常是不合适的。更合理的是URL ↓ 短生命周期、一次性的认证凭证 ↓ 后端服务端校验 ↓ 创建本地登录 Session6. 前端项目和后端渲染项目有什么区别这是一个非常好的追问。假设订单系统根本不是 React/VueJava Spring MVC而是浏览器 ↓ Java 服务 ↓ HTML它一样可以做 SSO。流程甚至更简单浏览器 ↓ 访问 Java 系统 ↓ Java 发现没有 Session ↓ 302 Redirect ↓ 认证中心 ↓ 认证中心发现已经登录 ↓ 302 Redirect ↓ Java 系统 callback ↓ Java 后端拿 ticket ↓ 服务端调用认证中心 ↓ 获取用户身份 ↓ 创建 Java Session ↓ Set-Cookie: JSESSIONIDxxx ↓ 返回页面所以SSO 本质上不是前端路由问题而是认证系统之间如何建立信任和传递认证结果的问题。这一点非常重要。7. 如果是现代 SPA 呢如果子系统是React Vue Angular现代项目更常见的方案不一定是 CAS。还可能使用OAuth 2.0 OIDC尤其是OIDC OpenID Connect可以理解成OAuth 2.0 用户身份认证 ↓ OIDC所以面试时最好不要说“不同一级域名必须使用 CAS。”这个说法太绝对。更准确的是跨一级域名不能靠 Cookie 共享解决需要引入中央认证中心具体可以使用 CAS、OIDC 等标准协议。这个回答明显更高级。8. state 到底干什么如果继续追问 OIDC / OAuth为什么要 state不要简单回答“state 防 CSRF。”可以进一步说客户端发起认证请求 ↓ 生成随机 state ↓ 保存本地 ↓ 带 state 跳转认证中心 ↓ 认证中心完成认证 ↓ 回调携带 state ↓ 客户端校验两边 state 是否一致例如客户端保存 state abc123跳转/auth? client_idxxx stateabc123回调/callback? codexxx stateabc123然后if(callbackState!savedState){reject();}核心目的就是确认这次回调确实对应当前客户端发起的那次认证请求避免攻击者伪造认证流程。所以可以说它用于防 CSRF但不要把state简化成“一个普通防 CSRF Token”。9. 用户退出登录怎么办这又是 SSO 的另一半登录统一退出也要考虑统一。假设认证中心 │ ├── 主系统 Session ├── 订单系统 Session └── 数据看板 Session用户在主系统点击退出不能只做删除主系统 Cookie否则可能出现主系统已退出 ❌ 订单系统还登录着 ✅ 数据看板还登录着 ✅这就不是完整的 SSO 退出。10. 统一登出怎么做一种典型架构是用户 ↓ 主系统 Logout ↓ 认证中心 ↓ 销毁中央登录态 ↓ 通知各个子系统 ↓ 子系统销毁自己的 Session例如认证中心 │ 全局 Session 删除 │ ┌───────────┼───────────┐ ↓ ↓ ↓ 主系统 订单系统 数据看板 ↓ ↓ ↓ Session Session Session 删除 删除 删除通知子系统的具体方式可以有很多HTTP 回调 消息队列 事件总线 前端重定向退出 标准协议提供的 Logout 机制不能简单说“统一登出就是 MQ 广播。”因为 MQ 只是一种工程实现方式不是 SSO 的必然要求。11. 这道题真正考什么其实不是考Cookie 怎么设置而是考你能不能把这个问题拆开登录态在哪里保存 ↓ 不同系统之间能不能共享 Cookie ↓ 不能共享怎么办 ↓ 有没有中央认证中心 ↓ 认证结果怎么安全传递 ↓ 怎么防重放 ↓ 怎么防 CSRF ↓ 子系统怎么建立自己的 Session ↓ 用户退出后怎么同步这才是这道题的核心。12. 面试官继续追问链这道题可以一路追到很深主系统登录后子系统怎么自动登录 ↓ 为什么不能直接共享 Cookie ↓ 什么情况下 Cookie 可以共享 ↓ 不同一级域名怎么办 ↓ CAS 是什么 ↓ CAS Ticket 和 Token 有什么区别 ↓ 为什么 Ticket 必须一次性 ↓ 为什么不能直接把 Token 放 URL ↓ state 是干什么的 ↓ OAuth 2.0 和 OIDC 什么关系 ↓ SPA 和后端渲染项目分别怎么接 ↓ Session 和 Token 怎么选 ↓ 用户退出后怎么实现统一登出 ↓ 多个子系统怎么通知 ↓ 如果认证中心挂了怎么办 ↓ 如果 Ticket 被截获怎么办 ↓ SSO 和权限控制有什么区别其中最后两个尤其容易拉开水平。13. 一个面试时可以直接说的版本第一段先说这个不要一上来背 CAS 全流程主系统登录后子系统能不能自动登录关键看它们能不能共享登录态。同一父域名下可以考虑 Cookie 共享如果是不同一级域名就不能直接共享 Cookie而是让多个系统依赖统一认证中心。子系统发现自己没登录就跳到认证中心认证中心确认用户已经登录后返回一次性的认证凭证子系统后端再向认证中心校验并建立自己的登录态。如果面试官继续追问 CAS经典 CAS 里这个一次性凭证就是 Ticket。Ticket 通过浏览器带回子系统但子系统不会直接信任它而是由后端拿 Ticket 去认证中心校验成功后创建自己的 Session。Ticket 用一次就失效这样可以降低重放风险。如果继续问统一登出退出登录也不能只删主系统自己的 Session而是要先销毁认证中心的全局登录态再通知各个子系统清理自己的局部 Session这样才能真正做到单点登录和统一登出。这三段基本就是这道题的主干答案。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑