单点登录的几种方案

视频讲解链接

单点登录存在原因

分布式微服务成为主流的情况下,需要解决只能在单个用户模块存储session的问题,其他模块需要能够同样取到用户的信息,避免用户反复登录。
在这里插入图片描述

方案一

Nginx代理,对IP进行hash,该IP生成的session存储在某一台服务器中
在这里插入图片描述

方案问题:

  1. 单点故障:某台服务器宕机,该服务器存储的所有session丢失,违背高可用。
  2. 所有服务器都具备全量模块,无法满足微服务拆分的需求

方案二:session同步

在这里插入图片描述问题:

  1. 各个微服务之间需要都进行同步,同一个session存储过多,信息冗余
  2. 滞后性问题:还没有完成同步就去调用模块功能,会出现问题
    优点:配置简单,修改Tomcat即可;基本满足了微服务需求。

方案三:第三方存储件存储session

[参考链接](https://blog.csdn.net/wzljiayou/article/details/109550565?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161594369116780255299779%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161594369116780255299779&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-12-10955
0565.first_rank_v2_pc_rank_v29&utm_term=%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95)

在这里插入图片描述
可以实现一个系统多个模块内部的单点登录。

难点:

  1. 唯一性标志key的生成。
    不能采用UUID:A系统生成的UUID能否被B系统采纳与使用?如何保证所有系统的UUID都是独一无二的?
    UUID作为sessionID是有风险的:不同系统的session是不一致的,有可能会产生重复id。
  2. 如何判断是否生成过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禁用场景。

猜你喜欢

转载自blog.csdn.net/weixin_38370441/article/details/115141201