公司系统较多,业务之间交集,做引流,不想重复开发,往往就需要内嵌:
一、嵌入方
1. 嵌入方式
//待修改 加每个参数的实际含义
<template>
<div class="iframe-container">
<iframe id="iframe" ref="iframeRef" :src="checkSrc()" width="100%" height="100%" allowfullscreen sandbox="allow-scripts allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-storage-access-by-user-activation allow-top-navigation-by-user-activation allow-downloads"></iframe>
</div>
</template>
Tips:
本身HTTP, 内嵌方 HTTPS,或者是HTTP 都支持
本身HTTPS,内嵌方是HTTP,浏览器会认为不安全,有时候HTTPS资源也可能被检测判为不安全,因此,如果自身系统,经常需要内嵌诸多外部系统,暂时以HTTP 方式运行可获取最大的兼容性
为保证客户打开网页一直走HTTP,可以让运维帮忙配置重定向,把HTTPS重定向到HTTP
-
内嵌会使得被嵌入方,普通cookie的设置和读取受到影响,如果被嵌入方 把登录token以cookie的方式存储,那么会导致网页登录失败
(1) 同源策略:
同源策略是浏览器的一项基本安全策略,它规定了来自不同源(即协议、域名、端口三者完全一致)的内容间不能相互访问资源。当iframe加载的是与主页面不同源的网页时,由于同源策略的限制,iframe内部网页通常无法访问主页面的cookie,反之亦然。(2) 第三方Cookie限制:
如果iframe加载的是第三方站点,浏览器可能会阻止iframe从顶级上下文中读取或写入
cookie,特别是当涉及到用户隐私和安全时,这种限制更为严格。(3) SameSite Cookie属性:
SameSite 是cookie的一个属性,用于指定cookie是否应该伴随跨站请求发送。默认情况
下,或当设置为 SameSite=Lax 时,浏览器将不允许在一个跨站上下文中(如iframe内)
发送非安全(non-secure)的SameSite cookie。被内嵌方如需存取cookie,设cookie时就要设这个属性(4) Secure Cookie属性:
若cookie设置了 Secure 属性,则cookie只能通过HTTPS协议传输,这意味着在非加密
HTTP连接中,iframe无法获取带有 Secure 属性的cookie。被内嵌方如需存取cookie,设cookie时就要设这个属性(5) P3P政策:
对于旧版Internet Explorer浏览器(已不再主流支持),iframe内的网页可能需要遵循
P3P(Platform for Privacy Preferences)隐私策略声明才能读取或写入cookie。如果没
有正确的P3P头信息,IE浏览器可能会阻止iframe中的cookie交互。(6) httpOnly:
该属性必须由客户端或者是中间层服务中设置,端上无法设置,将Cookie设置为HttpOnly是为了增加cookie的安全性,防止恶意脚本获取Cookie,从而防止XSS攻击和某些CSRF攻击。HttpOnly的cookie仅能通过HTTP(和HTTPS)协议访问,而不能通过JavaScript等脚本访问。这样即使有XSS攻击成功注入了恶意脚本,也无法读取到cookie的值,提高了cookie的安全性。值得注意的是如果在我们在内嵌网页的服务端或中间层服务对cookie中设置了httpOnly,那么第一次设置cookie会成功,但是第二次,在外部是http 的协议前提下,是无法修改的,而如果内嵌方需要设置cookie,我们现在都是设置 Secure和 SameSite两个属性,这样比如我们的iframe链接需要不断更新时,就能更新成功。 但值得注意的是如果在无痕的环境下,cookie 依然无法被覆盖。 因此一般我们采用内嵌方案时,对方需要登录并且是依赖cookie完成的整套登录校验,那就需要格外注意了。
2. 接收消息
function handleMessage(event) {
let data = event.data;
console.log(data)
}
// 也要做好每次进来的清除
onMounted(() => {
window.removeEventListener('message', handleMessage);
window.addEventListener("message", handleMessage, false);
});
// 或者在离开的时候
onUnmounted(() => {
window.removeEventListener('message', handleMessage);
});
3. 测试被嵌入方发来信号
// !!测试支付提示弹窗
setTimeout(() => {
window.parent.postMessage(
{
type: 'clickPay',
data: {
title: '订单提交通知',
roomGuest: 'XX',
phone: 'XX',
desc: 'XX'
},
},
'*'
);
}, 5000);
// 对接方
const handleMessage = (e) => {
const res = e?.data || {};
if (res.type === 'clickPay') {
console.log(res.data);
}
};
4. 帮助被内嵌系统免登陆实现
首先第一步就是要拿到token
1、同一个公司的登录往往是走公共,是统一的,此时token 可互通,把token传下去即可
2、如果不相通,也可让被嵌入方提供接口,我们去调接口,传入工号和姓名,或卡号等信息,注册,并得到token,然后也是参数的方式往下传递约定好参数传入
// 直接把对token 通过参数形式传给被嵌入方
<iframe data-v-278c76dc="" width="100%" height="441px" src="https://m.ly.com/hotel?AUTH_TOKEN=XXXXX&if=5006942" frameborder="0" sandbox="allow-same-origin allow-scripts"></iframe>
Tips:
- 1、iframe 内嵌可以在调试窗口,修改element中的链接直接触发重新加载
- 2、记得可以拿被嵌入方的链接 提前测试一下,可以关注下比如内嵌之后是否有部分资源,接口,图片加载异常,如果自身是https 域名的,那么这类情况大概率会出现
- 3、如果被内嵌方是cookie 处理登录流程的, 自身是http协议, 此时为了让被嵌入方可以完成登录,设置了secure 和same site 这些属性,并且为了更新没有设置httpOnly, 需要提醒用户不可用无痕浏览器,否则cookie 这套依然会行不通
- 4、不走参数,想要把token 传给被嵌入方,我们还有一种方式,那就是利用sdk,一般需要被嵌入方提供,我们调用, 这样也是一种把token传下去,且不暴露在外面的,更安全的方式
- 5、值得一提的是如果我们自身是https,而被嵌入方也是https, 公司所有站都实现了https 协议,未来也不用考率http 的可能,那么对于cookie更新这块,我们建议 httpOnly 属性也加上会更好!!
- 6、
- 7、在很多时候,我们需要不断尝试,才知道一些方案是否真的有效,不要意气用事,先入为主,道听途说, 内嵌接入前一定做好充分的尝试和调研
二、被嵌入方
- 1、约定好实际的参数情况,走window.postMessage,如上照做即可。
- 2、如果页面中存在各种情况。比如有些window.parent window.top window.self 等,操作, 一定要注意兼容问题,因为在iframe 环境中,会被认为想要操作, 可以参照 内嵌操作window兼容 来处理兼容性问题
- 3、最好是拿到token 解析,解决登录,有时候系统是需要走统一登录回跳,利用cookie 埋登录信息的情况,那么参考上面,对cookie的处理吧