Skip to content

单点登录(SSO)与第三方授权(OAuth2) ​


❓ 面试官:你们公司的系统有多个子系统(比如商城后台、物流系统、OA系统),怎么实现用户只要登录一次,就能无缝访问所有系统的?(单点登录 SSO 的原理) ​

频率:🔥🔥🔥🔥🔥

💡 一句话总结(先抛结论): 这叫单点登录(Single Sign-On, SSO)。核心思想是建立一个独立统一的认证中心(SSO Server),所有的子系统都不自己做登录,而是把未登录的用户踢给认证中心去处理。

📝 详细流程解析(同域与跨域的两种解法):

场景一:都在同一个主域名下(比如 a.company.com 和 b.company.com) 这种最简单,不需要复杂的 SSO 协议。

  1. 用户在 a.company.com 登录成功后,后端生成 Token。
  2. 把 Token 写到前端的 Cookie 里,并且把 Cookie 的 Domain 设置为父域名 .company.com。
  3. 这样用户再去访问 b.company.com 时,浏览器会自动带上这个父域名的 Cookie。b 系统的后端拿到 Token 去 Redis 里一查,发现验证通过,就直接放行了。

场景二:完全跨域(比如 www.taobao.com 和 www.tmall.com) 这是真正面试常考的复杂 SSO(通常基于 CAS 协议或 OAuth2 思想)。

  1. 用户访问天猫(未登录),天猫发现没票,把用户重定向跳转到统一的 sso.alibaba.com。
  2. 用户在 sso.alibaba.com 输入账号密码登录成功。
  3. SSO 中心生成一个全局票据(TGT),种在 SSO 自己的域下。同时带着一个临时授权码(Ticket)重定向回天猫。
  4. 天猫后台拿到这个 Ticket,去向 SSO 中心发请求验证真伪。
  5. 验证成功后,天猫自己给用户种一个天猫域下的局部 Cookie,用户在天猫就处于登录状态了。
  6. 精髓来了:如果此时用户再去访问淘宝,淘宝发现未登录,再次重定向到 sso.alibaba.com。这时候 SSO 发现该用户之前已经登录过(有全局 TGT 缓存),它根本不会弹出登录框,而是直接生成一个给淘宝用的 Ticket,瞬间重定向回淘宝。用户感知上就是:哎?我没输密码怎么淘宝也自动登录了?

❓ 面试官:能说说 OAuth2.0 的授权码模式(Authorization Code)的具体流程吗?微信扫码登录是怎么做的?【中高级】 ​

频率:🔥🔥🔥🔥

💡 一句话总结(先抛结论): OAuth2 是一种授权机制,用来让“第三方应用”在不知道用户账号密码的情况下,获取用户在“服务提供商”那边的数据(比如头像、昵称)。授权码模式是 OAuth2 中最严密、最安全的模式。

📝 拿微信扫码登录举例(通俗易懂的剧本):

假设我们的网站叫“掘金”,用户想用微信登录掘金。

  1. 第一步(重定向要授权码): 用户在掘金点击“微信登录”。掘金前端会把页面重定向跳转到微信的官方扫码页面。URL 里会带上掘金的 AppID 和一个 回调地址 Redirect_URI。

  2. 第二步(用户扫码同意): 用户拿出手机扫码,手机微信上弹出“掘金申请获取你的头像昵称”。用户点击同意。

  3. 第三步(微信发临时授权码 Code): 微信验证用户同意后,会再次进行重定向,跳回到刚才掘金传过去的 Redirect_URI,并在 URL 后面带上一个临时的授权码 Code(比如 ?code=12345)。

  4. 第四步(后端拿 Code 换 Token,这是最安全的一步!): 掘金的后端服务器拿到这个 Code 后,立刻在后台发一个 HTTP 请求给微信的服务器。 请求里带着:Code + AppID + AppSecret(掘金在微信那里的私钥,绝对不能泄露给前端)。 微信核对无误后,返回一个真正的 Access_Token(访问令牌)。

  5. 第五步(拿 Token 换取用户信息): 掘金后端拿到 Access_Token 后,再去调微信的 /userinfo 接口,拿到用户的微信头像和昵称。 然后掘金后端在自己的数据库里静默帮用户注册一个账号,并生成掘金自己的登录 JWT 返回给前端。整个登录大功告成!

🌟 连环追问:为什么不能微信直接返回 Token,非要中间插一个 Code? 因为如果微信直接重定向回前端,并把 Token 挂在 URL 后面,那就极度不安全!中间的恶意网络节点抓包就能拿到这个具备永久权限的 Token。 而有了 Code 之后,前端 URL 里只暴露了只能用一次、且只有 5 分钟有效期的废纸 Code。真正的 Token 是由掘金的后端和微信的后端在内网里悄悄交换的,完美避开了前端被劫持的风险。