父页面与子页面(Tab 页)Token 传递对接说明
概述
当用户在所属模块中点击 “开启” 按钮并保存后,父页面会在切换至对应的 Tab 页时,通过 HTML5
postMessage API 主动向子页面(iframe 内嵌页)传递一组鉴权 Token 参数。子页面需监听相应消息事件以获取这些参数,并用于后续接口请求的签名校验。鉴权参数具体内容(appid)需要在云客服管理后台的对接中心-鉴权信息进行获取,签名值加密内容与openapi鉴权参数加密逻辑一致,可参考本文档后的示例demo进行解密

1. 父页面行为
- 触发时机:用户完成“开启”操作并保存,且当前 Tab 页被激活(切换到该页)时。
- 传递方式:
window.postMessage(message, targetOrigin) - 发送的数据结构(
message对象):
json
{
"type": "tab-token",
"token": {
"appid": "xxx",
"timestamp": "xxx",
"nonce": "xxx",
"signature": "xxx"
}
}说明:
targetOrigin 建议设置为子页面的具体域名,以增强安全性(避免被恶意第三方截获)。2. 子页面接收方式以及加密对比方法
子页面(iframe 内)需在全局监听
message 事件,示例代码如下:javascript
window.addEventListener('message', function(event) {
// 建议校验消息来源(origin),防止跨域伪造
const allowedOrigins = ['https://your-parent-domain.com']; // 按需配置
if (!allowedOrigins.includes(event.origin)) {
return; // 忽略非法来源
}
const data = event.data;
if (data && data.type === 'tab-token') {
const token = data.token;
// token 结构:{ appid, timestamp, nonce, signature }
console.log('收到 Token:', token);
// 此处可存储 token 或直接用于后续 API 请求
// 例如:存储到全局变量或 Vuex/Redux 状态中
window.__token = token;
}
});
校验方法verifySignature
function verifySignature(appId, secretKey, nonce, timestamp, signature, ) {
const message = appId + timestamp + nonce;
const expectedSignature = Base64.stringify(
HmacSHA256(message, secretKey),
);
return expectedSignature === signature;
}
并
window.addEventListener('message', (event) => {
if(event.data.type === 'tab-token'){
const token = event.data.token
// 校验
// secretKey为双方约定好的secretKey
verifySignature(token.appId, secretKey, token.nonce, token.timestamp, token.signature)
// 方法返回true/false
}3. Token 参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
appid | string | 应用标识,用于识别调用方身份 |
timestamp | string | 当前时间戳(Unix 秒级或毫秒级,建议与后端约定一致) |
nonce | string | 随机字符串,用于防止重放攻击 |
signature | string | 签名值,由父页面按约定算法(如 HMAC-SHA256)生成,子方可验证 |
4. 安全建议(重要)
- 来源校验:子页面必须校验
event.origin,仅信任父页面所在域。 - 数据校验:接收到 token 后,建议子页面根据约定的签名算法(如
signature = hash(appid + timestamp + nonce + secret))重新计算并比对,防止中间人篡改。 - 过期处理:
timestamp应结合业务设置有效窗口(如 5 分钟),超时则拒绝使用。
5. 异常处理
- 若子页面未收到 type === 'tab-token' 的消息,可主动向父页面发送请求(通过 parent.postMessage,type为child-ready)要求重发。
- 建议子页面设置超时监听(如 3 秒),若未收到 Token 则展示“加载中”或“权限获取失败”提示。
示例子页面文件
html:
vue: