基于Cookie的SSO登录分析和实现
现在很多大的互联网公司都会有很多的应用,比如以下是淘宝网的截图:
天猫 聚划算 头条等都是不同的应用,有的甚至采用完全不同的域名,但是所有在淘宝注册的用户都是使用的一套用户名和口令,如果在这些系统直接切换做不到登陆状态的同步,体验是非常差的。再举个栗子,很多公司内部系统也有很多个,比如HR系统,财务系统,考勤系统等等,如果员工在一个系统登陆了,跳转到另外一个系统还需要登陆,就会让人很不爽...
基于此,SSO(Single Sign On)
应运而生。当然,我们来现实这个需求的方法有很多种,使用Cookie是其中比较简单的方式,主要需要解决的问题是:Cookie
是不能跨域传递的,如何将一个域的Cookie
通知给其它应用(不在同一个域)?
so
,如果你对cookie
机制不太熟悉,请先google
,并大致了解为什么cookie
会设计成不能跨域等相关问题。
SSO有以下几种方式实现
当我们的子系统都在一个父级域名下时,我们可以将Cookie种在父域下,这样浏览器同域名下的Cookie则可以共享,这样可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO。
但是,后面我们发现这种方式有几种弊端:
a. 所有同域名的系统都能获取SessionID,易被修改且不安全;
b. 跨域无法使用。
这种实现的SSO有以下几个步骤:
a. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面;
b. 判断SSO是否已经登录;
c. 如果已经登录,直接跳转到回调地址,并返回认证ticket;
d. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket;
e. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录。
前面已经说了,如何通过Cookie
来实现SSO
,主要是如何解决跨域问题。首先来谈谈Set-Cookie
中的domain
属性。
为了让Http
协议在一定程度上保持上下文,server
在响应的头部可以加入Set-Cookie
来写入一些数据到客户端,Set-Cookie
中的domain
字段用来表示这个cookie
所在的域。
栗子:
我们访问www.cookieexm.com
,如果server
在返回头部中加入了Set-Cookie
,如果不指定domain
,那么默认这个cookie
的域就是www.cookieexm.com
,也就是只有访问www.cookieexm.com
时客户端才会把这个cookie
返给服务端。
如果我们指定domain
为.cookieexm.com
,那么客户端在访问以下域名:www.cookieexm.com www1.cookieexm.com a.cookieexm.com ***.cookieexm.com
时都能够把cookie
返回。
所以,我们得出一条结论:客户端对cookie的domain的匹配是从结尾进行匹配的,有了这个基础,我们就可以实现我们的SSO
登陆了。
cookie中需要注意的
假设我们需要在如下子系统 **.a1.a2 **.b1.b2 **.c1.c2
间实现单点登录,首先我们需要一个专门用于单点登陆的认证系统(sso.s1.s2)。假设目前系统处于未登录状态,访问www.a1.a2
为例: