单点登录的三种实现方式

在B/S系统中,登录功能通常都是基于Cookie来实现的。当用户登陆成功后一般会将登录状态记录到session中,或者给已过户签发一个token,无论是哪一种方式,都需要在客户端保存一些信息(session id  或者token)并且要求客户端在每次请求中携带它,在这样的场景下 使用cookie无疑是最方便的,因此我们一般会将sessionId或者token保存在cookie中,当服务器收到请求后,会通过验证cookie中的信息来判断用户是否登录。

单点登录(single sign on , sso)是指统一账号平台下的多个应用系统中,用户只需要登录一次,即可以访问多有相互信任的应用系统。例如:百度贴吧和百度地图是百度公司旗下的两个不同的应用系统,如果用户在百度贴吧登陆过之后,当他访问百度地图时无需再次登录,那么就说明百度地图和百度贴吧之间实现了单点登录。

单点登录就是不同的用系统之间共享登录状态,因为不同系统往往存在不同的域名,尽管共享了session,但是sessionId往往是保存在Cookie中的,因此存在作用域的限制。cookie无法跨域名传递,也就是说用户在访问app1.com中登录后,sessionid仅仅在留在器访问app1.com时才会自动在请求头中携带,而当浏览器访问app2.com时,sessionid是无法携带的。实现单点登录的关键就在于如何让cookie中的sessionId或者token在多个域中共享。

实现方式一:父域cookie

再具体实现之前,先看一下cookie的作用域。

Cookie的作用域由domain属性和path属性共同决定。domain属性的有效值为当前域或者其父域的域名或者ip地址,在tomcat中,domain属性的默认值为当前域的域名或ip地址,如果将Cookie的属性设置为当前域的父域,那么就认为他是父域的cookie。Cookie有一个特点,即父域的Cookie被子域所共享,换言之,子域将会继承父域的Cookie。利用Cookie的这个特点我们只需要将Cookie的domain属性设置为父域的域名(主域名),同时将path属性设置为根目录。

总结:此种方式比较简单,但是不支持跨主域名。

实现方式二:认证中心

我们可以部署一个认证中心,认证中心就是一个专门负责处理独立登录请求的web服务。

用户同意在认证中心登录,登陆成功后,认证中心会记录用户的登录状态,并将token写入到Cookie。(这个Cookie是认证中心的Cookie)应用系统是访问不到的。

应用系统检查当前请求有没有携带token,如果没有,说明用户未在系统中个进行登录,那么就将跳转至认证中心,由于这个操作就会将认证中心的Cookie自动带过去,因此,认证中心能够根据Cookie知道用户已经登录过了,就不会让其再次登录,并会跳转回目标的URL,并在跳转前生成一个Token,拼接在目标url后面。回传给目标应用系统。

应用系统拿到Token后,还需要向认证中心验证此Token的合法性,防止恶意伪造。确认无误后,应用系统会记录用户的登录状态,并将Token写入到Cookie,此次访问放行。(注意这个Token是当前应用系统的,其他系统访问不到)当用户再次访问当前系统时,就会自动带上这个Token,应用系统验证Token合法,就没有认证中心的事了。

这里顺便介绍两款认证中心的开源实现:

  • Apereo CAS 是一个企业级单点登录系统,其中 CAS 的意思是”Central Authentication Service“。它最初是耶鲁大学实验室的项目,后来转让给了 JASIG 组织,项目更名为 JASIG CAS,后来该组织并入了Apereo 基金会,项目也随之更名为 Apereo CAS。

  • XXL-SSO 是一个简易的单点登录系统,由大众点评工程师许雪里个人开发,代码比较简单,没有做安全控制,因而不推荐直接应用在项目中,这里列出来仅供参考。

总结:此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法。

实现方式三:LocalStorage 跨域

前面,我们说实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享。

父域 Cookie 确实是一种不错的解决方案,但是不支持跨域。那么有没有什么奇淫技巧能够让 Cookie 跨域传递呢?

很遗憾,浏览器对 Cookie 的跨域限制越来越严格。Chrome 浏览器还给 Cookie 新增了一个 SameSite 属性,此举几乎禁止了一切跨域请求的 Cookie 传递(超链接除外),并且只有当使用 HTTPs 协议时,才有可能被允许在 AJAX 跨域请求中接受服务器传来的 Cookie。

不过,在前后端分离的情况下,完全可以不使用 Cookie,我们可以选择将 Session ID (或 Token )保存到浏览器的 LocalStorage 中,让前端在每次向后端发送请求时,主动将 LocalStorage 的数据传递给服务端。这些都是由前端来控制的,后端需要做的仅仅是在用户登录成功后,将 Session ID (或 Token )放在响应体中传递给前端。

在这样的场景下,单点登录完全可以在前端实现。前端拿到 Session ID (或 Token )后,除了将它写入自己的 LocalStorage 中之外,还可以通过特殊手段将它写入多个其他域下的 LocalStorage 中。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值