如何识别跨源打开者身份?仅允许Google Docs等特定源访问站点
验证Google Docs来源的解决方案
由于浏览器同源策略的限制,跨域场景下window.opener.origin会被屏蔽,无法直接读取。要确认请求来自Google Docs,必须通过postMessage完成双向身份验证,具体实现如下:
核心思路
通过主动发起验证请求+双向确认的方式:
- Google Docs侧打开你的网站后,主动发送带自定义标识的验证消息,并附带自身origin
- 你的网站侧接收消息后,先验证origin后缀是否为
.googleusercontent.com,再校验消息标识防止伪造,验证通过后返回确认信号并执行对应业务逻辑
具体代码实现
Google Docs 侧代码
const targetWindow = window.open("https://www.example.com/feature"); // 等待目标页面加载完成后发送验证消息(也可以监听页面load事件替代setTimeout,更可靠) setTimeout(() => { targetWindow.postMessage( { type: "DOCS_ORIGIN_VERIFY", payload: "docs-valid-token" }, // 自定义标识,防止伪造消息 "https://www.example.com" // 指定目标网站origin,避免消息泄露给无关站点 ); }, 1000); // 接收目标网站的验证确认 window.addEventListener("message", (e) => { if (e.origin === "https://www.example.com" && e.data.type === "VERIFY_SUCCESS") { // 验证完成,可进行后续数据通信 console.log("目标网站已确认身份"); } });
你的网站侧代码
let isDocsVerified = false; window.addEventListener("message", (e) => { // 第一步:验证消息来源是否为Google Docs域名 if (!e.origin.endsWith(".googleusercontent.com")) { alert("请从Google Docs打开此页面!"); return; } // 第二步:验证消息类型和自定义标识,防止伪造消息攻击 if (e.data.type === "DOCS_ORIGIN_VERIFY" && e.data.payload === "docs-valid-token") { // 第三步:返回确认消息给Google Docs e.source.postMessage({ type: "VERIFY_SUCCESS" }, e.origin); // 标记验证通过,执行业务逻辑 isDocsVerified = true; showLoginWindow(); } }); // 后续数据传输需先校验验证状态 function sendDataToDocs(data) { if (isDocsVerified && window.opener) { window.opener.postMessage( { type: "DATA_TRANSFER", content: data }, e.origin // 始终指定具体origin,不要用* ); } }
附加疑问解答
为什么A(Google Docs)打开B(你的网站)时,B无法直接获取A的源?
这是浏览器同源策略的安全防护机制:跨域场景下,浏览器会严格限制目标页面读取 opener 的源信息,哪怕A主动发起了打开请求。这一设计是为了保护来源网站的隐私——避免恶意网站通过window.opener窃取来源网站的敏感数据,或者伪装成来源网站进行欺诈行为。
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

