专业的JAVA编程教程与资源

网站首页 > java教程 正文

4000字长文,带你了解单点登录

temp10 2024-11-20 21:46:08 java教程 13 ℃ 0 评论

什么是单点登录

单点登录是指在多个应用系统中,用户只需要登录任意一个系统,就可以访问其他的互相信任的系统。比如说我在天猫登录后,在浏览器上输入淘宝的域名,你就已经登录成功了。

为什么需要单点登录

为了方便,如果一款产品的用户体验很差劲,那么基本上是没有用户愿意持续使用的。

4000字长文,带你了解单点登录

通过单点登录,可以让用户在多系统中灵活跳转而不必重新登录,能有效提升用户体验。


常见的登录实现

首先我们后端有个拦截器,每次请求接口时都会在拦截器内部进行判断:根据Cookie中传递的SessionId判断用户信息是否已经保存在Session中。如果不存在,说明用户未登录,让浏览器跳转到登录页进行登录。

登录验证成功后,把用户信息写入到 服务器Session中。于是通过Cookie中的SessionId和服务器建立了会话。

并且一般来说,浏览器中的Cookie不会设置过期时间,而是在服务端的Session中设置,由服务端来控制用户的登录态。

单点登录的设计思路

首先我们要了解,单点登录其实就是用户的登录态在多个系统间进行共享。我们可以这样思考,假如用户在 A系统 登录后,然后点击 B系统,能够把用户相关信息给带过去,然后在 B系统中判断存在用户信息, 从而进行登录。这样做对于用户来说是完全无感知的,只需要在系统层面帮助用户进行登录即可。

传递数据到前端还是后端

如果是通过浏览器页面传递信息,前端拿到用户信息后,可以调用 B系统 服务端接口进行登录,与B系统建立会话。

如果是传递到 B系统 后端服务器,需要在服务器进行登录,然后带上用户信息重定向到B系统前端页面,这时候建立会话完成。

如何传递数据

既然是通过浏览器传递数据,有两种方式,第一种是通过在Url上拼接参数,比如 www.baidu.com?userId=123 。

第二种是通过Cookie的形式传递,但是由于Cookie不能跨域,就导致了部分局限性。

为了体现对技术的追求,我偷偷的补充了一句:不过我发现在淘宝的Cookie中,能够看到天猫的domain,好像是用Jsonp实现的。

安全性如何保证

不管是URL还是Cookie传递数据,如何保证数据的安全性呢?

保证数据的安全性总的来说有几种实现:

  1. 从软件层面上进行保证,比如说可见性等。
  2. 通过加密算法对数据进行加密。

因为从浏览器层面保证数据不可见不太现实,所以可以对数据进行加密,并且这个数据加解密的过程应该由服务端来实现

比如:用户在 系统A 登录后,系统A 的服务端通过某种加密算法以及某个秘钥对用户数据进行加密,接着返回给前端。系统A 页面跳转到系统B时带上这个加密信息,接着调用系统B服务端接口进行登录。系统B 通过解密数据获取登录者的用户信息进行登录即可。

单点登录具体是如何实现

“重头戏来了”,因为我们所有系统的顶级域名都是一样的,因此不会存在跨域问题。为了降低接入成本,我们采用的是 Cookie加密 的形式。

比如用户在 系统A 登录后,系统A会往浏览器中写入Cookie, Key 为userInfo,value值为用户A的accountId。当然这个accountId是加密过的。

然后用户在访问系统B的页面时,由于属于同一个顶级域名,会带上 Cookie。调用系统B接口时,判断 Cookie中存在用户信息,如果存在,通过Secret进行解密获取用户的accountId,随后把用户数据放到Session中,从而进行登录。

这样做还有一个好处就是:用户可以直接在浏览器中输入域名进行跳转,而不是需要在 系统A 点击跳转到系统B。毕竟一般的用户都是把链接保存在书签的。

加密的Secret是怎么实现的

Secret采用的是系统约定的形式,这个值在系统中以加密的形式进行存储,并且使用的配置中心,再加上我们系统使用的是专用网络,基本不存在泄漏的风险。


使用Cookie 可能会存在被攻击的风险,你知道哪些吗

使用Cookie存储的方式可能会受到Xss攻击,也就是攻击者在页面上注入恶意脚本,然后在浏览器上运行这段脚本,从而获取用户的数据,比如Cookie等,危害数据安全。这有点像我们后端的SQL注入

所以我们的系统在设置用户Cookie时都会设置 HttpOnly=true,这样通过js脚本将无法读取到cookie信息,增强了使用Cookie的安全性。

另外除了Xss攻击外,还会存在Csrf攻击,也就是跨站请求伪造,攻击者一般会诱导用户进入第三方网站。然后在第三方网站中,通过比较吸引人的链接让用户点击。从而冒充用户对被攻击的网站执行某项操作的目的。


用户登录的时效性怎么保证

在单系统条件下,如果是标准的 Cookie-Session 机制,用户登录后调用接口,这个 Session 会进行续签,从而让会话保持下去。会话的生命周期变成了主要由服务端来保证

但是通过目前的这种形式,通过Cookie中是否存在用户信息判断是否登录,会出现一个情况就是只要这个用户信息也就是Cookie一直存在,那么用户就永远不会退出。(因为我们只会对数据进行解密,并且用户在登录后,Cookie并不会设置有效期),也就是说这个会话的生命周期变成了由 Cookie 来保证。

所以我们有两种方案,一种是对 Cookie 添加过期时间,比如 30 分钟,只要Cookie消失了,说明用户登录状态失效。第二种是在userInfo这个Cookie的Value值中添加过期信息,然后每次接口调用时服务端判断是否超时。

添加过期时间这种方案可行吗

问题点在于续签问题,这两种方式不可避免的都需要刷新,也就是说用户只要请求后端服务,都需要重新设置Cookie的过期时间或者修改Value的值。这个相对的就比较蠢了,而且还会有性能问题。

所以我们项目的目前方案是由Cookie来保证这个会话的生命周期,并且不进行续签

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表