javascript - 在私有浏览器中加载跨域 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);
}
}
通常步骤是这样的:
- 登录站点 1
- 按下加载 Site2 的按钮
- Site2 加载一个包含 Site1 的 iframe
- 由于用户已经登录到 Site1,他们已经登录到 iframe 内的站点
- Site2 执行 postMessage 以获取 jwt
- Site1 以 jwt 响应
- 一切正常,我们现在有了 jwt,所以我们可以使用 API
在正常情况下,这一切都可以正常工作,但由于某种原因,这在私人浏览器中不起作用。
- 登录站点 1
- 按下加载 Site2 的按钮
- Site2 加载一个包含 Site1 的 iframe
- 加载的 Site1 没有用户登录
- Site2 执行 postMessage 并得到 false 响应,因为他们没有登录
- 我重定向到 Site1 的登录屏幕,因为我假设他们实际上已注销
以某种方式加载 iframe 会导致用户完全注销(转到另一个选项卡中的主页显示用户实际上已注销)
奇怪的是,这只发生在第一次在私人窗口中,如果用户再次重复前几个步骤,页面第二次正常工作(除非他们关闭私人浏览器并重新开始)所以如果你按照这个,它工作正常
- 登录站点 1
- 按下加载 Site2 的按钮
- Site2 加载一个包含 Site1 的 iframe
- 加载的 Site1 没有用户登录
- Site2 执行 postMessage 并得到 false 响应,因为他们没有登录
- 我重定向到 Site1 的登录屏幕,因为我假设他们实际上已注销
- 再次登录 Site1
- 按下加载 Site2 的按钮
- Site2 加载一个包含 Site1 的 iframe
- 由于用户已经登录到 Site1,他们已经登录到 iframe 内的站点
- Site2 执行 postMessage 以获取 jwt
- Site1 以 jwt 响应
- 一切正常
postMessage 是否缺少我不知道的东西?提前致谢。
解决方案
事实证明,这种行为是由 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
推荐阅读
- flutter - Flutter 地理定位器插件 Geolocator().placemarkFromAddress() 和 Geolocator().placemarkFromCoordinates() 不起作用
- javascript - 递归函数在Javascript中运行时如何执行回调函数?
- javascript - 如何显示带有动态变量的 toastr 消息
- r - R:在销售数据中插入缺失观察的行
- sql - 如何加入多个表进行计数?
- node.js - Aws lambda图像上传问题
- c++ - 如何针对 C++ Qt 中的链接器优化我的项目?
- python - anaconda自带的python解释器和官方的python解释器发行版有区别吗?
- python - 如何访问类中函数中的列表?
- python-3.6 - 预提交:使用 python 3.6.8 运行 flake8