单点登录方案

单点登录

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

SSO 一般都需要一个独立的认证中心(passport),子系统的登录均得通过passport,子系统本身将不参与登录操作。SSO是在多个应用系统中,用户只需要登录一次,同步更新子系统状态就可以访问所有相互信任的应用系统。

比如,有两个管理系统,Application1和Application2,当Application1系统进入时,先判断是否登录,登录就跳出,没有登录的话就跳到SSO系统,在SSO系统完成登录,最后将登录验证信息(比如token)携带跳转到刚刚的应用板块Application1。当然如果登录系统是统一的话,Application2也要更新状态。Application2就可以免登录了。当然每次子系统真正进入系统操作前要验证登录验证信息(比如token)有效。

如何实现
一、同域名下的单点登录

cookie的domin属性设置为当前域的父域,并且父域的cookie会被子域所共享。path属性默认为web应用的上下文路径

利用 Cookie 的这个特点,没错,我们只需要将Cookie的domain属性设置为父域的域名(主域名),同时将 Cookie的path属性设置为根路径,将 Session ID(或 Token)保存到父域中。这样所有的子域应用就都可以访问到这个Cookie。

以阿里云服务为例

https://www.aliyun.com/

https://codeup.aliyun.com/

登录成功后清除cookie试试

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

如果是不同域的情况下,Cookie是不共享的,这里我们可以部署一个认证中心,用于专门处理登录请求的独立的 Web服务

用户统一在认证中心进行登录,登录成功后,认证中心记录用户的登录状态,并将 token 写入 Cookie(注意这个 Cookie是认证中心的,应用系统是访问不到的)

应用系统检查当前请求,或请求头有没有 Token,如果没有,说明用户在当前系统中尚未登录,那么就将页面跳转至认证中心

此时认证中心能够根据 Cookie(是否存储token或是否有效期内) 知道用户是否已经登录过了

如果认证中心发现用户尚未登录,则返回登录页面,等待用户登录;如果发现用户已经登录过了,就不会让用户再次登录了,而是会跳转回目标 URL,并在跳转前生成携带Token,拼接在目标URL 的后面,回传给目标应用系统。(此时有人会问,是不是只要知道链接,任何人复制浏览就能打开,是的)所以个人方案是在浏览器生成唯一指纹npm install @fingerprintjs/fingerprintjs@^2,每台客户端上浏览器每次刷新打开是唯一不变值,用来传递到SSO,登录时与账号密码一起返回后端生成token。

应用系统拿到 Token之后,还需要向认证中心确认下 token 的合法性,防止用户伪造。确认无误后,应用系统记录用户的登录状态,并将 Token写入Cookie,然后给本次访问放行。(注意此时这个 cookie 是当前应用系统的)当用户再次访问当前应用系统时,就会自动带上这个 token,应用系统验证 token 发现用户已登录,于是就不会有认证中心什么事了。

说明:以上是以token存储到cookie为例,具体与实际项目为主。个人习惯SSO中可以cookie(毕竟有过期时间设置), 应用系统可以存储到loaclstorage中。

此种实现方式相对复杂,,支持跨域,扩展性好,是单点登录的标准做法。

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

单点登录完全可以在前端实现。前端拿到token后,除了将它写入自己的 localStorage 中之外,还可以通过特殊手段将它写入多个其他域下的 localStorage 中。


// 登录页面
// 登录成功获取token
var token = result.data.token;
 
// 动态创建一个不可见的iframe,在iframe中加载一个跨域HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/index.html";
document.body.append(iframe);
// 使用postMessage()方法将token传递给iframe
setTimeout(function () {
    iframe.contentWindow.postMessage(token, "http://app1.com"); // 域名与上面一致,路径不一样没事,,不影响功能。
}, 4000);
setTimeout(function () {
    iframe.remove();
}, 6000);
 

// 在这个iframe所加载的ttp://app1.com 的HTML中绑定一个事件监听器,当事件被触发时,把接收到的token数据写入localStorage; 之后初次加载该页面
window.addEventListener('message', function (event) {
    localStorage.setItem('token', event.data)
}, false);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值