当前位置: 代码迷 >> 综合 >> 单点登录 打开新窗口 解决跨域 的 另类方案
  详细解决方案

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

热度:32   发布时间:2024-03-08 21:33:26.0

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

刚开始解决这个问题的方法是 用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 {window.sso_logined_func({code:500, msg:'登录失败,请重新登录'}, login_type)}});}}}

 

  相关解决方案