系统太多,多账号互通如何实现?

背景

最近开发新产品,然后老板说我们现在系统太多了,每次切换系统登录太麻烦了,能不能做个优化,同一账号互通掉。作为一个资深架构狮,老板的要求肯定要满足,安排!

一个公司产品矩阵比较丰富的时候,用户在不同系统之间来回切换,固然对产品用户体验上较差,并且增加用户密码管理成本。

也没有很好地利用内部流量进行用户打通,并且每个产品的独立体系会导致产品安全度下降。

因此实现集团产品的单点登录对用户使用体验以及效率提升有很大的帮助。那么如何实现统一认证呢?我们先了解一下传统的身份验证方式。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

传统 Session 机制及身份认证方案

504ac3103e081f8276ae09ae25e51b0e.jpeg

众所周知,http 是无状态的协议,因此客户每次通过浏览器访问 web。

页面,请求到服务端时,服务器都会新建线程,打开新的会话,而且服务器也不会自动维护客户的上下文信息。

比如我们现在要实现一个电商内的购物车功能,要怎么才能知道哪些购物车请求对应的是来自同一个客户的请求呢?

因此出现了 session 这个概念,session 就是一种保存上下文信息的机制,他是面向用户的,每一个 SessionID 对应着一个用户,并且保存在服务端中。

session 主要以 cookie 或 URL 重写为基础的来实现的,默认使用 cookie 来实现,系统会创造一个名为 JSESSIONID 的变量输出到 cookie 中。

JSESSIONID 是存储于浏览器内存中的,并不是写到硬盘上的,如果我们把浏览器的cookie 禁止,则 web 服务器会采用 URL 重写的方式传递 Sessionid,我们就可以在地址栏看到 sessionid=KWJHUG6JJM65HS2K6 之类的字符串。

通常 JSESSIONID 是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的 sessionid,这样我们信息共享的目的就达不到了。

服务器端的 session 的机制

当服务端收到客户端的请求时候,首先判断请求里是否包含了 JSESSIONID 的 sessionId,如果存在说明已经创建过了,直接从内存中拿出来使用,如果查询不到,说明是无效的。

如果客户请求不包含 sessionid,则为此客户创建一个 session 并且生成一个与此 session 相关联的 sessionid,这个 sessionid 将在本次响应中返回给客户端保存。

对每次 http 请求,都经历以下步骤处理:

  • 服务端首先查找对应的 cookie 的值(sessionid)。
  • 根据 sessionid,从服务器端 session 存储中获取对应 id 的 session 数据,进行返回。
  • 如果找不到 sessionid,服务器端就创建 session,生成 sessionid 对应的 cookie,写入到响应头中。

session 是由服务端生成的,并且以散列表的形式保存在内存中。

基于 seesion 的身份认证主要流程如下:

85ad72d2e03c25d89b2dfdc91ca3c0f5.jpeg

因为 http 请求是无状态请求,所以在 Web 领域,大部分都是通过这种方式解决。但是这么做有什么问题呢?我们接着看。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

随着技术的发展,用户流量增大,单个服务器已经不能满足系统的需要了,分布式架构开始流行。

62d99d4f37dd39f37d7fb4400c27f521.jpeg

通常都会把系统部署在多台服务器上,通过负载均衡把请求分发到其中的一台服务器上,这样很可能同一个用户的请求被分发到不同的服务器上。

因为 session 是保存在服务器上的,那么很有可能第一次请求访问的 A 服务器,创建了 session,但是第二次访问到了 B 服务器,这时就会出现取不到 session 的情况。

我们知道,Session 一般是用来存会话全局的用户信息(不仅仅是登陆方面的问题),用来简化/加速后续的业务请求。

传统的 session 由服务器端生成并存储,当应用进行分布式集群部署的时候,如何保证不同服务器上 session 信息能够共享呢?

Session 共享一般有两种思路:

  • session 复制
  • session 集中存储
①session 复制

session 复制即将不同服务器上 session 数据进行复制,用户登录,修改,注销时,将 session 信息同时也复制到其他机器上面去。

这种实现的问题就是实现成本高,维护难度大,并且会存在延迟登问题。

②session 集中存储

集中存储就是将获取 session 单独放在一个服务中进行存储,所有获取 session 的统一来这个服务中去取。

这样就避免了同步和维护多套 session 的问题。一般我们都是使用 redis 进行集中式存储 session。

多服务下的登陆困境及 SSO 方案

d8c503b8cf1bcccc3efc4d67b6c5c84f.jpeg

如果企业做大了之后,一般都有很多的业务支持系统为其提供相应的管理和 IT 服务,按照传统的验证方式访问多系统,每个单独的系统都会有自己的安全体系和身份认证系统。

进入每个系统都需要进行登录,获取 session,再通过 session 访问对应系统资源。

这样的局面不仅给管理上带来了很大的困难,对客户来说也极不友好,那么如何让客户只需登陆一次,就可以进入多个系统,而不需要重新登录呢?

“单点登录”就是专为解决此类问题的。其大致思想流程如下:通过一个 ticket 进行串接各系统间的用户信息。

SSO 的底层原理 CAS

我们知道对于完全不同域名的系统,cookie 是无法跨域名共享的,因此 sessionId 在页面端也无法共享,因此需要实现单店登录,就需要启用一个专门用来登录的域名如(ouath.com)来提供所有系统的 sessionId。

当业务系统被打开时,借助中心授权系统进行登录,整体流程如下:

  • 当 b.com 打开时,发现自己未登陆,于是跳转到 ouath.com 去登陆
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值