单点登录
单点登录
什么是单点登录?
举个场景,假设我们的系统被切割为N个部分:商城、论坛、直播、社交…… 如果用户每访问一个模块都要登录一次,那么用户将会疯掉, 为了优化用户体验,我们急需一套机制将这N个系统的认证授权互通共享,让用户在一个系统登录之后,便可以畅通无阻的访问其它所有系统。
单点登录可以做到:**在多个互相信任的系统中,用户只需登录一次,就可以访问所有系统。
**
三种单点登录模式
1: 前端同域,后端同Redis
2: 前端不同域,后端同Redis
3: 前端不同域,后端不同Redis
前端同域,后端同Redis
这种情况,多个前端部署的域名同域,后端可以访问同一个Redis。我们可以通过共享Cookie
的方式进行单点登录。
1: 使用共享Cookie
的方式来解决前端Token共享的问题
2: 使用Redis
在不同的后端来解决Session共享的问题
所谓共享Cookie,就是主域名Cookie在二级域名下的共享,举个例子:写在父域名stp.com
下的Cookie,在s1.stp.com
、s2.stp.com
等子域名都是可以共享访问的。
前端不同域,后端同Redis
这种情况会导致我们共享Cookie方式失效,我们需要再不同域中传递Token。
用户在 子系统 点击
[登录]
按钮。用户跳转到子系统登录接口
/sso/login
,并携带back参数
记录初始页面URL。
- 形如:
http://{sso-client}/sso/login?back=xxx
- 形如:
子系统检测到此用户尚未登录,再次将其重定向至SSO认证中心,并携带
redirect参数
记录子系统的登录页URL(后面SSO登录成功跳转页面)。- 形如:
http://{sso-server}/sso/auth?redirect=xxx?back=xxx
- 形如:
用户进入了 SSO认证中心 的登录页面,开始登录。
用户 输入账号密码 并 登录成功,SSO认证中心再次将用户重定向至子系统的登录接口
/sso/login
,并携带ticket码
参数。- 形如:
http://{sso-client}/sso/login?back=xxx&ticket=xxxxxxxxx
- 形如:
子系统根据
ticket码
从SSO-Redis
中获取账号id,并在子系统登录此账号会话。子系统将用户再次重定向至最初始的
back
页面。
前端不同域,后端不同Redis
- Client 端无法直连 Redis 校验 ticket,取出账号id。
- Client 端无法与 Server 端共用一套会话,需要自行维护子会话。
- 由于不是一套会话,所以无法“一次注销,全端下线”,需要额外编写代码完成单点注销。
需要注意的是,做好接口鉴权,防止恶意请求调用,泄露用户信息。
解决方案就是使用Http请求SSO-SERVER,将获取信息获取同步到本地客户端进行保存。
除了账号id,我们可能还需要将用户的昵称、头像等信息从 Server端 带到 Client端,即:用户资料的同步。
在模式二中我们只需要将需要同步的资料放到 SaSession 即可,但是在模式三中两端不再连接同一个Redis,这时候我们需要通过http接口来同步信息:
如何注销
- Client 端在校验 ticket 时,将注销回调地址发送到 Server 端。
- Server 端将此 Client 的注销回调地址存储到 Set 集合。
- Client 端向 Server 端发送单点注销请求。
- Server 端遍历Set集合,逐个通知 Client 端下线。
- Server 端注销下线。
- 单点注销完成。