你有没有遇到过公司每一个产品,都要开发一个用户系统,浪费开发成本不说,用户体验还不好,用户要记住每一个产品的用户密码,每个产品都要重复登录,问题重重,要是能登录一次别的一些列产品就都登录了那该多好,SSO(Single Sign On)单点登录,能帮你解决这些问题。
我在这里来说一下单点登录实现原理,希望能让大家对单点登录更了解,并应用之。我这里以phpCAS的例子来说讲解。
首先我们想到单点登录可能是通过在根域下设置一个cookie,然后只要在这个域下的都可以共享cookie,这种方式最大的问题就是不能实现跨域(虽然网上有很多跨域的解决方案,比如header方式,但是各个浏览器支持的都不是很好),并且很不安全。所以CAS实现了另一种方式——cas server和cas client分离,也就是说单点登录服务器单独部署,其他client调用它,从而实现单点登录。具体流程如下图
1、浏览器访问单点登录的网站,如果session存在就返回数据,如果不存在就跳转到cas server(一个单独域名的服务)
2、如果有已经登录过,通过检测cookie,cas server就会302跳转通过url返回Ticket(Ticket是随机且唯一)到网站,如果没有登录过,就跳转到cas server登录页面进行登录,登录成功设置cookie,然后302跳转返回Ticket到网站,同时cas server会存储改Ticket、cookie和网站host的对应关系。
3、 网站接收到Ticket后通过cas server提供的校验url去校验Ticket,cas server确认后返回成功,网站把当前的sessionid换成Ticket(session_id(Ticket)),然后返回浏览器请求数据
4、当用户再访问网站的时候,就会判断当前session是否登录
单点登录就说完了,其实没有太复杂的技术,主要是实现的思想,说完单点登录大家一定想知道的是如何单点登出呢?接下来我再分析一下单点登出的原理:
1、用户点击登出,网站先清除当前网站的session信息,然后跳转到cas server退出URL
2、cas server接收到登出请求后删除cookie或session信息,并且通过单点登录时候记录的cookie和host、Ticket对应关系,遍历host给网站发送post登出请求(这里有一个Tip,就是在cas server退出页面通过iframe等方式把向所有host发出退出请求)
3、网站接收到登出请求后,获取Ticket,并且把Ticket换成当前的sessionid,模拟用户登录,然后销毁session完成登出
以上是本人通过研究phpCAS获得的结论,这个只是最基本的模式,还有很多复杂模式,比如代理模式等等,有经验的朋友欢迎交流!
谢谢!