单点登录
- 单点登录存在原因
- 方案一
- 方案二:session同步
- 方案三:第三方存储件存储session
- 方案四:对接第三方系统的单点登录
视频讲解链接
单点登录存在原因 分布式微服务成为主流的情况下,需要解决只能在单个用户模块存储session的问题,其他模块需要能够同样取到用户的信息,避免用户反复登录。
文章图片
方案一 Nginx代理,对IP进行hash,该IP生成的session存储在某一台服务器中
文章图片
方案问题:
- 单点故障:某台服务器宕机,该服务器存储的所有session丢失,违背高可用。
- 所有服务器都具备全量模块,无法满足微服务拆分的需求
文章图片
问题:
- 各个微服务之间需要都进行同步,同一个session存储过多,信息冗余
- 滞后性问题:还没有完成同步就去调用模块功能,会出现问题
优点:配置简单,修改Tomcat即可;基本满足了微服务需求。
0565.first_rank_v2_pc_rank_v29&utm_term=%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95)
文章图片
可以实现一个系统多个模块内部的单点登录。
难点:
- 唯一性标志key的生成。
不能采用UUID:A系统生成的UUID能否被B系统采纳与使用?如何保证所有系统的UUID都是独一无二的?
UUID作为sessionID是有风险的:不同系统的session是不一致的,有可能会产生重复id。 - 如何判断是否生成过session
1.回写给客户端,之后客户端发起请求时携带该key,说明用户登录信息已经存在在第三方存储件了。
写入到哪里:可以写入cookie、也可以写入sessionStore。
2.唯一ID的生成方式:雪花算法等。
方案四:对接第三方系统的单点登录 Oauth2.0解决的核心问题:避免该系统(比如说百度网盘)拿到你第三方系统(比如QQ)的账号密码。
文章图片
第二步的一个例子:
文章图片
第三步:需要携带clientID,指明是由哪个系统请求的第三方系统登录
Status code:哪种认证方式。callback:回调函数:防止其他系统仿冒百度网盘获取到权限,所以需要回调函数,这样即便其他服务调用这个URL,回调也会发送到百度网盘的服务器上
【其他|单点登录的几种方案】第四步:QQ只是充当了验证平台的操作,没必要去存储登录百度网盘的session信息。
响应回去的内容需要满足:1.加密。2.需要存储信息(因为QQ不存储,但是要给一个唯一标志)3.过期时间
这就引出了JWT,同时搞定了加密需求、唯一标志以及过期时间。
JWT介绍
核心:非对称加密
三部分:
头部:主要设置一些规范信息,签名部分的编码格式就在头部中声明。
载荷:token中存放有效信息的部分,比如用户名,用户角色,过期时间等,但是不要放密码,会泄露!
签名:将头部与载荷分别采用base64编码后,用“.”相连,再加入盐,最后使用头部声明的编码类型进行编码,就得到了签名。
基本原理:同时生成两把密钥:私钥和公钥,私钥隐秘保存,公钥可以下发给信任客户端
加密解密都是在QQ方进行,百度网盘只是获取token
第五步:拿到token访问QQ服务器,QQ收到token并解密。
引申:
基于Cookie的单点登录
将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有权限则从Cookie中取出用户名密码进行登录,让用户从某种意义上觉得只登录了一次。
该方式缺点就是多次传送用户名密码,增加被盗风险,以及不能跨域。cookie相对于session而言安全性从差,并且无法处理cookie禁用场景。
推荐阅读
- Java|昨天面了个腾讯拿39K出来的,让我见识到什么是基础的天花板
- Java|共36万字,为上岸Alibaba,我把Github上Java面试题都整理了一遍
- java|单点登录方案
- Java|Redis Pipeline原来是这么用的
- java|java 调度_几种任务调度的Java实现方法与比较
- JSP|两万字速通JSP
- cookie|一文了解Session
- Redis|面试官(熟悉Redis,那聊聊Redis主从复制(我画了13张图讲明白了))
- 《我们一起去大厂》系列|面试官看我简历写精通redis,让我聊聊sds是什么()