👀SSO单点登录 知多少
为撒我们要使用单点登录
通常情况下我们开发一套系统时,我们都会写一套登录页面。当用户需要访问系统时需要先进行账号登录然后进入系统使用。但是当我们有多个系统时难道需要用户登录多次吗?显然这种方式是不优雅的😶🌫️,此时就轮到单点登录登场了。本文将主要以前端的视角来聊一聊该如何落地单点登录。
单点登录的英文名叫做:Single Sign On(简称SSO)😶🌫️
单点登录能干嘛
简单粗暴的说单点登录就是
一处登录 处处登录 🤡
单点登录在前端的系统模型
单点登录实施方案
单点登录目前有两种方案
- cookie 共享方案(子域名方案)
- ticket 方案(凭证交换)
这两个方案是有共同点的,我们看看它们有哪些共同的部分
- 需要一个独立的登录系统
- 通用重定向的方式完成子系统登录
结合以上可以发现,这两个方案其实在前端的差异性并不大,主要就是需要考虑如何实现登录态共享。
cookie 共享方案
传统的登录方式是用户在登录页完成登录,然后后端通过 set-cookie 将 token 写入到浏览器的 cookie 当中之后的每次请求都会携带token完成身份验证。此时的登录模块和业务模块是同一系统下的不同页面。
单点登录模型下的登录模块和业务模块是独立的不同系统
结合以上流程图我们来分析一波,图中的A
和sso
都是example.com
的子域名,当用户访问A-client
时会向A-server
发送身份验证请求检验当前请求是否携带有效token,如无效则返回特定 code A-client
接到返回后根据 code 做出不同响应。
A-server
返回 token 有效,则继续保持对A-client
的访问。A-server
返回 token 无效。A-client
重定向至SSO-client
并携带redirect参数http://sso.example.com?redirect=a.example.com
。当用户在
SSO-client
完成登录后(SSO-server 通过 set-cookie 设置 token 为子域名可访问),再通过redirect参数重定向回A-client
。回到
A-client
后A-client
再次向A-server
发起身份验证,这次请求会默认携带上domain=example.com
的cookie.token,A-server
收到token检验有效后,返回用户信息继续保持用户对A-client
的有效访问。
至此单点登录的核心逻辑就梳理完成了。
注意:以上是以每套系统都有独立的后端服务(同源)做出的流程,但是有时候我们的后端服可能是同一个,这时候我们在 ABC系统中的请求可能会有跨域/跨站等问题。
解决办法也很多,需要看是跨域,还是跨站问题。
这里贴一个跨域的处理方法 note.youdao.com/s/Tjuuv8Mv 也可以用反向代理去规避跨域问题。
同源:协议+主机名+端口 都相同
同站:二级域名+顶级域名 相同即可
ticket 临时凭证
ticket 方案总体上和 cookie 方案总体差不多,主要区别在于获取 token 的形式不同。
cookie 方案主要是依赖浏览的特性来完成 token 共享。
ticket 则是由各系统携带 ticket 这个临时凭证去换取token
从上图可以看出 ticket 方案不同的地方在于:
用户首次访问
A-client
时 token 不存在A-client
会重定向至SSO-client
,当用户在SSO-client
登录成功后SSO-server
会 set-cookie 将 token 注入到浏览器中(7天免登录),并返回 ticket 参数SSO-client
收到登录成功结果后再次带着 ticket 参数重定向回A-client (http://a.example.com?ticket=xxxxxxx)
。此时
A-client
时会多一个 ticket 参数。当
A-client
中的 token 过期时或不存在时,如果 ticket 存在A-server
就会带着ticket去请求SSO-server
检验ticket是否有效,当SSO-server
返回有效的话就表示用户在SSO
中是有效登录的。验证成功后
A-server
下发 token set-cookie 进A-client
的cookie中。
至此完成登录。
以上多是以前端的角度在分析单点登录的实现逻辑,还有很多可以修改的地方。例如后端是同一套服务,token是放在cookie,还是local storage或是JS内存中都是根据业务需求改变的。
以及安全问题,这里就不展开讨论啦
来源:juejin.cn/post/7254027262885855291