单点登录(SSO)与第三方授权(OAuth2)
❓ 面试官:你们公司的系统有多个子系统(比如商城后台、物流系统、OA系统),怎么实现用户只要登录一次,就能无缝访问所有系统的?(单点登录 SSO 的原理)
频率:🔥🔥🔥🔥🔥
💡 一句话总结(先抛结论): 这叫单点登录(Single Sign-On, SSO)。核心思想是建立一个独立统一的认证中心(SSO Server),所有的子系统都不自己做登录,而是把未登录的用户踢给认证中心去处理。
📝 详细流程解析(同域与跨域的两种解法):
场景一:都在同一个主域名下(比如 a.company.com 和 b.company.com) 这种最简单,不需要复杂的 SSO 协议。
- 用户在
a.company.com登录成功后,后端生成 Token。 - 把 Token 写到前端的 Cookie 里,并且把 Cookie 的 Domain 设置为父域名
.company.com。 - 这样用户再去访问
b.company.com时,浏览器会自动带上这个父域名的 Cookie。b 系统的后端拿到 Token 去 Redis 里一查,发现验证通过,就直接放行了。
场景二:完全跨域(比如 www.taobao.com 和 www.tmall.com) 这是真正面试常考的复杂 SSO(通常基于 CAS 协议或 OAuth2 思想)。
- 用户访问天猫(未登录),天猫发现没票,把用户重定向跳转到统一的
sso.alibaba.com。 - 用户在
sso.alibaba.com输入账号密码登录成功。 - SSO 中心生成一个全局票据(TGT),种在 SSO 自己的域下。同时带着一个临时授权码(Ticket)重定向回天猫。
- 天猫后台拿到这个 Ticket,去向 SSO 中心发请求验证真伪。
- 验证成功后,天猫自己给用户种一个天猫域下的局部 Cookie,用户在天猫就处于登录状态了。
- 精髓来了:如果此时用户再去访问淘宝,淘宝发现未登录,再次重定向到
sso.alibaba.com。这时候 SSO 发现该用户之前已经登录过(有全局 TGT 缓存),它根本不会弹出登录框,而是直接生成一个给淘宝用的 Ticket,瞬间重定向回淘宝。用户感知上就是:哎?我没输密码怎么淘宝也自动登录了?
❓ 面试官:能说说 OAuth2.0 的授权码模式(Authorization Code)的具体流程吗?微信扫码登录是怎么做的?【中高级】
频率:🔥🔥🔥🔥
💡 一句话总结(先抛结论): OAuth2 是一种授权机制,用来让“第三方应用”在不知道用户账号密码的情况下,获取用户在“服务提供商”那边的数据(比如头像、昵称)。授权码模式是 OAuth2 中最严密、最安全的模式。
📝 拿微信扫码登录举例(通俗易懂的剧本):
假设我们的网站叫“掘金”,用户想用微信登录掘金。
第一步(重定向要授权码): 用户在掘金点击“微信登录”。掘金前端会把页面重定向跳转到微信的官方扫码页面。URL 里会带上掘金的
AppID和一个回调地址 Redirect_URI。第二步(用户扫码同意): 用户拿出手机扫码,手机微信上弹出“掘金申请获取你的头像昵称”。用户点击同意。
第三步(微信发临时授权码 Code): 微信验证用户同意后,会再次进行重定向,跳回到刚才掘金传过去的
Redirect_URI,并在 URL 后面带上一个临时的授权码Code(比如?code=12345)。第四步(后端拿 Code 换 Token,这是最安全的一步!): 掘金的后端服务器拿到这个
Code后,立刻在后台发一个 HTTP 请求给微信的服务器。 请求里带着:Code+AppID+AppSecret(掘金在微信那里的私钥,绝对不能泄露给前端)。 微信核对无误后,返回一个真正的Access_Token(访问令牌)。第五步(拿 Token 换取用户信息): 掘金后端拿到
Access_Token后,再去调微信的/userinfo接口,拿到用户的微信头像和昵称。 然后掘金后端在自己的数据库里静默帮用户注册一个账号,并生成掘金自己的登录 JWT 返回给前端。整个登录大功告成!
🌟 连环追问:为什么不能微信直接返回 Token,非要中间插一个 Code? 因为如果微信直接重定向回前端,并把 Token 挂在 URL 后面,那就极度不安全!中间的恶意网络节点抓包就能拿到这个具备永久权限的 Token。 而有了 Code 之后,前端 URL 里只暴露了只能用一次、且只有 5 分钟有效期的废纸 Code。真正的 Token 是由掘金的后端和微信的后端在内网里悄悄交换的,完美避开了前端被劫持的风险。