单点登录
单点登录的英文名叫做:
Single Sign On
(简称SSO)
- 它是一种身份验证解决方案,可让用户通过一次性用户身份验证登录多个应用程序和网站。
单点登录就是在多个系统中,用户只需一次登录,各个系统即可感知该用户已经登录。
- 所谓一次登录,处处登录,同样一处退出,处处退出。
以前,一般的系统都是单系统,也就是说所有的功能都在同一个系统上。
- 后来,为了合理利用资源和降低耦合性,于是把单系统拆分成多个子系统。
比如阿里系的淘宝和天猫,很明显地可以知道这是两个系统
- 但是在使用的时候,登录了天猫,淘宝也会自动登录。
同域名下的单点登录
一个企业一般情况下只有一个域名
- 通过二级域名区分不同的系统。
比如有个域名
a.com
,同时有两个业务系统service1.a.com
和service2.a.com
- 要做单点登录(
SSO
),需要一个登录系统sso.a.com
。- 用户只要在
sso.a.com
登录,那么service1.a.com
和service2.a.com
就也登录了。用户在
sso.a.com
中登录之后,其实是在sso.a.com
的服务端session中记录了登录状态
- 同时在浏览器端的
sso.a.com
下写入了Cookie。怎么才能让
service1.a.com
和service2.a.com
登录?有两个问题:
Cookie跨域:
- Cookie是不能跨域的
- Cookie的domain属性是
sso.a.com
,在给service1.a.com
和service2.a.com
发送请求是带不上的。Session不共享:
- sso、service1和service2是不同的应用,它们的session存在自己的应用内,是不共享的。
第一个问题,sso登录以后,可以将Cookie的域设置为顶域,即
.a.com
这样所有子域的系统都可以访问到顶域的Cookie。
在设置Cookie时,只能设置顶域和自己的域,不能设置其他的域。
- 比如:不能在自己的系统中给
baidu.com
的域设置Cookie。共享Session的解决方案例如:
- 把Session数据放在Redis中
不同域下的单点登录
将登录单独抽取成SSO系统,并且有两个应用 app1 和 app2 以及用户A,分别是:
- app1:
www.app1.com
- app2:
www.app2.com
- 认证中心SSO:
www.sso.com
用户想要访问app1(
www.app1.com
),app1(www.app1.com
)发现用户并没有登录
- 于是重定向到sso认证中心,并将自己的地址作为参数。
SSO认证中心发现用户未登录,将用户引导至登录页面,用户进行输入用户名和密码进行登录
- 用户与认证中心建立全局会话(根据用户信息生成一个
token
,写到Cookie中,保存在浏览器上)。认证中心重定向回app1(
www.app1.com
),并把Token携带过去给app1接着,系统A去sso认证中心验证这个Token是否正确
- 如果正确,则系统A和用户建立局部会话(创建Session)。
到此,系统A和用户已经是登录状态了。


登录流程
注销流程
扫码登录
扫码登录功能
无需在网页上输入任何账号和密码,只需要通过手机上的APP,如微信、淘宝、QQ等等。
- 使用扫描功能,扫描网页上的二维码,确认登录,就可以完成网页端登录。
扫码登录整体流程
访问PC端二维码生成页面,PC端请求服务端获取
二维码ID
服务端生成相应的
二维码ID
- 设置二维码的过期时间,状态等
PC获取
二维码ID
,生成相应的二维码手机端扫描二维码,获取
二维码ID
手机端将
手机端token
和二维码ID
发送给服务端,确认登录服务端校验
手机端token
- 根据
手机端token
和二维码ID
生成PC端token
PC端通过轮询方式请求服务端:
- 通过
二维码ID
获取二维码状态,如果已成功,返回PC token
,登录成功
获取二维码状态
PC端可以通过获取二维码的状态来进行相应的响应:
- 二维码
未扫描
:无操作- 二维码
已失效
:提示刷新二维码- 二维码
已成功
:从服务端获取PC token
轮询:
- 客户端会每隔一段时间就主动给服务端发送一次二维码状态的查询请求。
长轮询:
- 客户端主动给服务端发送二维码状态的查询请求,服务端会按情况对请求进行阻塞
- 直至二维码信息更新或超时。
- 当客户端接收到返回结果后,若二维码仍未被扫描,则会继续发送查询请求
- 直至状态变化(已失效或已成功)。
Websocket:
- 前端在生成二维码后,会与后端建立连接,一旦后端发现二维码状态变化
- 可直接通过建立的连接主动推送信息给前端。