单点登录 打开新窗口 解决跨域 的 另类方案

单点登录是要求多域名 下共用一套登录的逻辑和数据,这个时候肯定会出现跨域问题

刚开始解决这个问题的方法是 用window.open打开的新窗口进行等待用户登录操作,原窗口进行 ajax轮询服务端接口 判断用户是否已登录。单点登录 并且不影响原界面的逻辑是实现了,但是要ajax轮询请求。(还有一种方案就是 可以通过爬取 第三方登录页面的二维码进行登录,但是这种方案逻辑太过于繁琐,而且针对不同平台的登录 都要单独写逻辑,所以不适用)

在实现了功能后 跨平台、不影响原界面 的单点登录功能后,决定优化一下,假如用户一旦增大,服务器压力必然爆表,优化的内容肯定就是ajax轮询了。

既然两个域名两个网页,那么必然跨域,cookie等这些肯定是用不上的,设置 父子页面通讯也过于繁琐并且没有保障的感觉。 我注意到 w_obj = window.open 函数返回的是 新窗口的对象,可以控制窗口关闭和判断窗口是否已关闭,但是调用 w_obj .name 时却提示跨域,那么有没有什么其他类似w_obj.closed的字段 是没有被跨域限制的呢?

打印了 w_obj,经过多次尝试,终于找到了一个 类似 w_obj.closed的字段:w_obj.length,找到文档

length:设置或返回窗口中的框架数量

文档说的框架是指 iframe 的数量,那么理论逻辑就走通了。思路就是:窗口a点击登录,弹出窗口b,窗口a进行 定时判断 w_obj.length 的值,窗口b进行第三方登录操作,登录成功后跳转到指定带有多个iframe的页面,窗口a判断出w_obj.length的值发生变化,则进行 请求判断用户是否已登录,如果登录成功则关闭窗口b。

php:

                    echo   "<style>
                                iframe {
                                    display:none;
                                }
                            </style>
                            <iframe></iframe>
                            <iframe></iframe>
                            <iframe></iframe>
                            <iframe></iframe>
                            <iframe></iframe>
                            <iframe></iframe>
                            ";
                    die;

 

js: 


              // 居中打开 500*500 的新窗口 用于第三方登录
              var w_obj = window.open(this.url, "_blank", "scrollbars=yes,resizable=1,modal=false,alwaysRaised=yes,height=500,width=500,top="+(window.screen.availHeight/2-250)+",left="+(window.screen.availWidth/2-250));

            console.log(w_obj)
            console.log(w_obj.frames)
            // console.log(w_obj.innerHeight)

            // 定时回调
            var interval = setInterval(is_login, 500)

            // 判断是否登录
            function is_login()
            {

            if (w_obj != null && w_obj.closed){
                    // 我的窗口被关闭!
                    interval = window.clearInterval(interval)
                    window.sso_logined_func({code:509, msg:'请重新登录'}, login_type)
            } else{
                    // console.log(w_obj.innerHeight)

                    // console.log(w_obj.length)
                    // 平台给出登录成功的信号,则进行获取登录成功后的数据
                    if(w_obj.length == 6) {
                      console.log('登录成功')
                      var result;
                      Ajax.get(window.host_url + window.api_path ,
                      {
                          type: 'token',
                      },
                      function(result ){
                          if (result.code == 200 && result.content != null) {
                              w_obj.close();
                              interval = window.clearInterval(interval)
                              window.sso_logined_func(result, login_type)
                          } else {
                              w_obj.close();
                              interval = window.clearInterval(interval)
                              window.sso_logined_func({code:500, msg:'登录失败,请重新登录'}, login_type)
                          }
                      });
                    }
                }
            }

 

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页