首页 > 解决方案 > 在私有浏览器中加载跨域 iframe 会注销用户

问题描述

我正在与一个客户合作,我在一个子域上制作一个小型的专用异地。他们希望我在用户点击按钮时使用他们的 API 发出简单的发布请求,但客户端不希望用户再次登录,而是希望他们使用来自主站点的访问令牌。所以我要求他们的工程师使用访问令牌添加对来自我的子域的 postMessage 的响应

域结构将是这样的:

站点 1 - https://www.example.com

站点 2 - https://sub.example.com

还有一个非常简单的例子,说明我拥有什么以及他们拥有什么:

//set the src of the iframe
$("#main-site-iframe").attr("src", "https://www.example.com");
//wait for the main site page to open
$("#main-site-iframe")[0].onload = () => {
    //my page posts a message to their site
    $("#my-iframe")[0].contentWindow.postMessage("jwt", "https://www.example.com");  
};
//their site listens for a request
window.addEventListener('message', tokenRequest, false);
function tokenRequest(e) {
    //make sure the request is from the correct subdomain
    if(e.origin == 'https://sub.example.com')
    {
        //respond with the access token
        e.source.postMessage(authJWT, e.origin);
    }
}

通常步骤是这样的:

在正常情况下,这一切都可以正常工作,但由于某种原因,这在私人浏览器中不起作用。

以某种方式加载 iframe 会导致用户完全注销(转到另一个选项卡中的主页显示用户实际上已注销)

奇怪的是,这只发生在第一次在私人窗口中,如果用户再次重复前几个步骤,页面第二次正常工作(除非他们关闭私人浏览器并重新开始)所以如果你按照这个,它工作正常

postMessage 是否缺少我不知道的东西?提前致谢。

标签: javascripthtmljqueryiframe

解决方案


事实证明,这种行为是由 http 与 https 的一些来回引起的。开发服务器没有 ssl 证书,所以它从来不是问题(它总是使用 http),而临时服务器有,但它没有强制执行(所以它可以在 http 和 https 之间切换)这实际上可以在生产中使用生产强制执行 https 它只是在暂存时失败,因为未强制执行 https。

由于浏览器将 http 和 https 视为单独的页面,因此会话令牌不在另一个本地存储中,具体取决于首先登录的页面。它是这样的:

Login to Site1 on https
Press a button that loads Site2 on http
Site2 loads an iframe that has Site1 but in http
Loads Site1 in http does NOT have the user logged in
Site2 does a postMessage and gets a response of false because they are not logged in
Redirect to Site1's Login Screen but this time on http
User logs in again on http not https
Press a button that loads Site2 on http
Loads Site1 in http and DOES have the user logged in this time
Everything works

推荐阅读