单点登录
什么是单点登录?
一、什么是SSO
SSO( Single Sign-On ),中文意即单点登录,单点登录是一种控制多个相关但彼此独立的系统的访问权限,拥有这一权限的用户可以使用单一的ID和密码访问某个或多个系统从而避免使用不同的用户名或密码,或者通过某种配置无缝地登录每个系统。
SSO的一种较为通俗的定义是:SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。
术语比较绕,简单概括:一次登录,全部访问。
单点登录包含三个核心元素,即:用户、系统、验证中心。
二、SSO示例
阿里系的淘宝和天猫,很明显地我们可以知道这是两个系统,但是你在使用的时候,登录了天猫,淘宝也会自动登录。
三、SSO要解决的问题(多系统登录的问题与解决)
3.1 Session不共享问题
单系统登录功能主要是用 Session 保存用户信息来实现的,但我们清楚的是:多系统即可能有多个 Tomcat,而 Session 是依赖当前系统的 Tomcat,所以系统A 的 Session 和系统B 的 Session 是不共享的。
不共享会发生什么?A系统登陆的用户,无法在B系统上直接使用。
解决系统之间的 Session 不共享问题有以下几种方案:
- Tomcat集群Session全局复制(集群内每个tomcat的session完全同步)【会影响集群的性能呢,不建议】
- 根据请求的IP进行Hash映射到对应的机器上(这就相当于请求的IP一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
- 把Session数据放在Redis中(使用Redis模拟Session)【建议】
-
我们可以将登录功能单独抽取出来,做成一个子系
SSO(登录系统)的逻辑如下:
- SSO系统生成一个token,并将用户信息存到Redis中,并设置过期时间
- 其他系统请求SSO系统进行登录,得到SSO返回的token,写到Cookie中
- 每次请求时,Cookie都会带上,拦截器得到token,判断是否已经登录
至此,其实我们会发现其实就两个变化:
- 将登陆功能抽取为一个系统(SSO),其他系统请求SSO进行登录
- 本来将用户信息存到Session,现在将用户信息存到Redis
3.2 Cookie跨域问题
上面我们解决了Session不能共享的问题,但其实还有另一个问题。Cookie是不能跨域的
比如说,我们请求 https://www.google.com/ 时,浏览器会自动把google.com的Cookie带过去给google的服务器,而不会把 https://www.baidu.com/ 的Cookie带过去给google的服务器。
这就意味着,由于域名不同,用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去。
针对Cookie存在跨域问题,有几种解决方案:
- 服务端将Cookie写到客户端后,客户端对Cookie进行解析,将Token解析出来,此后请求都把这个Token带上就行了
- 多个域名共享Cookie,在写到客户端的时候设置Cookie的domain。
- 将Token保存在SessionStroage中(不依赖Cookie就没有跨域的问题了)
到这里,我们已经可以实现单点登录了。