关于javascript:面试官说说什么是单点登录如何实现

6次阅读

共计 3162 个字符,预计需要花费 8 分钟才能阅读完成。

一、是什么

单点登录(Single Sign On),简称为 SSO,是目前比拟风行的企业业务整合的解决方案之一

SSO 的定义是在多个利用零碎中,用户只须要登录一次就能够拜访所有相互信任的利用零碎

SSO 个别都须要一个独立的认证核心(passport),子系统的登录均得通过passport,子系统自身将不参加登录操作

当一个零碎胜利登录当前,passport将会颁发一个令牌给各个子系统,子系统能够拿着令牌会获取各自的受爱护资源,为了缩小频繁认证,各个子系统在被 passport 受权当前,会建设一个部分会话,在肯定工夫内能够无需再次向 passport 发动认证

上图有四个零碎,别离是 Application1Application2Application3、和SSO,当Application1Application2Application3 须要登录时,将跳到 SSO 零碎,SSO零碎实现登录,其余的利用零碎也就随之登录了

举个例子

淘宝、天猫都属于阿里旗下,当用户登录淘宝后,再关上天猫,零碎便主动帮用户登录了天猫,这种景象就属于单点登录

二、如何实现

同域名下的单点登录

cookiedomin 属性设置为以后域的父域,并且父域的 cookie 会被子域所共享。path属性默认为 web 利用的上下文门路

利用 Cookie 的这个特点,没错,咱们只须要将 Cookie domain属性设置为父域的域名(主域名),同时将 Cookie path 属性设置为根门路,将 Session ID(或 Token)保留到父域中。这样所有的子域利用就都能够拜访到这个 Cookie

不过这要求利用零碎的域名需建设在一个独特的主域名之下,如 tieba.baidu.commap.baidu.com,它们都建设在 baidu.com 这个主域名之下,那么它们就能够通过这种形式来实现单点登录

不同域名下的单点登录(一)

如果是不同域的状况下,Cookie是不共享的,这里咱们能够部署一个认证核心,用于专门解决登录申请的独立的 Web 服务

用户对立在认证核心进行登录,登录胜利后,认证核心记录用户的登录状态,并将 token 写入 Cookie(留神这个 Cookie 是认证核心的,利用零碎是拜访不到的)

利用零碎查看以后申请有没有 Token,如果没有,阐明用户在以后零碎中尚未登录,那么就将页面跳转至认证核心

因为这个操作会将认证核心的 Cookie 主动带过来,因而,认证核心可能依据 Cookie 晓得用户是否曾经登录过了

如果认证核心发现用户尚未登录,则返回登录页面,期待用户登录

如果发现用户曾经登录过了,就不会让用户再次登录了,而是会跳转回指标 URL ,并在跳转前生成一个 Token,拼接在指标 URL 的前面,回传给指标利用零碎

利用零碎拿到 Token 之后,还须要向认证核心确认下 Token 的合法性,避免用户伪造。确认无误后,利用零碎记录用户的登录状态,并将 Token 写入 Cookie,而后给本次拜访放行。(留神这个 Cookie 是以后利用零碎的)当用户再次拜访以后利用零碎时,就会主动带上这个 Token,利用系统验证 Token 发现用户已登录,于是就不会有认证核心什么事了

此种实现形式绝对简单,反对跨域,扩展性好,是单点登录的规范做法

不同域名下的单点登录(二)

能够抉择将 Session ID(或 Token)保留到浏览器的 LocalStorage 中,让前端在每次向后端发送申请时,被动将 LocalStorage 的数据传递给服务端

这些都是由前端来管制的,后端须要做的仅仅是在用户登录胜利后,将 Session ID (或 Token )放在响应体中传递给前端

单点登录齐全能够在前端实现。前端拿到 Session ID (或 Token)后,除了将它写入本人的 LocalStorage 中之外,还能够通过非凡伎俩将它写入多个其余域下的 LocalStorage

要害代码如下:

// 获取 token
var token = result.data.token;
 
// 动态创建一个不可见的 iframe,在 iframe 中加载一个跨域 HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 应用 postMessage()办法将 token 传递给 iframe
setTimeout(function () {iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {iframe.remove();
}, 6000);
 
// 在这个 iframe 所加载的 HTML 中绑定一个事件监听器,当事件被触发时,把接管到的 token 数据写入 localStorage
window.addEventListener('message', function (event) {localStorage.setItem('token', event.data)
}, false);

前端通过 iframe+postMessage() 形式,将同一份 Token 写入到了多个域下的 LocalStorage 中,前端每次在向后端发送申请之前,都会被动从 LocalStorage 中读取 Token 并在申请中携带,这样就实现了同一份 Token 被多个域所共享

此种实现形式齐全由前端管制,简直不须要后端参加,同样反对跨域

三、流程

单点登录的流程图如下所示:

  • 用户拜访零碎 1 的受爱护资源,零碎 1 发现用户未登录,跳转至 sso 认证核心,并将本人的地址作为参数
  • sso 认证核心发现用户未登录,将用户疏导至登录页面
  • 用户输出用户名明码提交登录申请
  • sso 认证核心校验用户信息,创立用户与 sso 认证核心之间的会话,称为全局会话,同时创立受权令牌
  • sso 认证核心带着令牌跳转会最后的申请地址(零碎 1)
  • 零碎 1 拿到令牌,去 sso 认证核心校验令牌是否无效
  • sso 认证核心校验令牌,返回无效,注册零碎 1
  • 零碎 1 应用该令牌创立与用户的会话,称为部分会话,返回受爱护资源
  • 用户拜访零碎 2 的受爱护资源
  • 零碎 2 发现用户未登录,跳转至 sso 认证核心,并将本人的地址作为参数
  • sso 认证核心发现用户已登录,跳转回零碎 2 的地址,并附上令牌
  • 零碎 2 拿到令牌,去 sso 认证核心校验令牌是否无效
  • sso 认证核心校验令牌,返回无效,注册零碎 2
  • 零碎 2 应用该令牌创立与用户的部分会话,返回受爱护资源

用户登录胜利之后,会与 sso 认证核心及各个子系统建设会话,用户与 sso 认证核心建设的会话称为全局会话

用户与各个子系统建设的会话称为部分会话,部分会话建设之后,用户拜访子系统受爱护资源将不再通过 sso 认证核心

全局会话与部分会话有如下束缚关系:

  • 部分会话存在,全局会话肯定存在
  • 全局会话存在,部分会话不肯定存在
  • 全局会话销毁,部分会话必须销毁

参考文献

  • https://blog.csdn.net/weixin_…
  • https://baike.baidu.com/item/…
  • https://juejin.cn/post/684490…

往期

  • 面试官:谈谈 this 对象的了解
  • 面试官:JavaScript 中执行上下文和执行栈是什么?
  • 面试官:说说 JavaScript 中的事件模型
  • 面试官:typeof 与 instanceof 区别
  • 面试官:解释下什么是事件代理?利用场景?
  • 面试官:说说 new 操作符具体干了什么?
  • 面试官:ajax 原理是什么?如何实现?
  • 面试官:bind、call、apply 区别?如何实现一个 bind?
  • 面试官:说说你对正则表达式的了解?利用场景?
  • 面试官:说说你对事件循环的了解

返回 github 面试题库查看更多

正文完
 0