Shared Worker 可安全跨 iframe 共享用户状态凭证,需结合 OAuth2/JWT 生命周期管理、受信 iframe 注册校验、按需响应+主动通知双通道同步、IndexedDB 加密持久化及 Safari 兼容处理。

Shared Worker 确实可以用于跨多个 iframe 共享用户状态凭证,但关键在于“凭证”不能直接存为明文变量,也不能依赖内存常驻——必须结合安全策略、生命周期管理和通信隔离机制来实现真正可用的方案。
Shared Worker 本身不存储凭证,而是协调凭证的获取、刷新与分发逻辑
Shared Worker 的全局作用域中可维护一个统一的认证会话(如 access_token、refresh_token、expires_at),但它不等于把 token 字符串裸露在内存里。实际做法是:Worker 封装完整的 OAuth2 / JWT 生命周期管理,包括自动刷新、过期检查、失败降级,并只向已验证身份的 iframe 发送脱敏或时效性受限的状态快照(例如 { isAuthenticated: true, role: 'user', expiresIn: 120000 }),而非原始 token。
iframe 必须主动注册并声明上下文身份
每个 iframe 在连接 Shared Worker 后,需发送带标识的初始化消息:
port.postMessage({
type: 'register',
contextId: 'dashboard-iframe', // 或从 window.name / URL path 提取
permissions: ['read:profile', 'write:settings']
});Worker 收到后,校验该 iframe 是否来自可信源(可通过 event.source 的 origin 检查,或比对预设白名单),再将其 port 加入受信客户端 Map。未注册或来源异常的 iframe,Worker 直接忽略其后续所有凭证请求。
凭证同步不是广播,而是按需响应 + 主动通知双通道
- 页面/iframe 发起
{ type: 'get_auth_state' }→ Worker 返回当前会话摘要(不含敏感字段) - 当 Worker 检测到 token 刷新成功、过期或登出时 → 主动向所有已注册端口广播
{ type: 'auth_changed', payload: { event: 'refreshed', ts: Date.now() } } - iframe 根据事件类型决定是否重新拉取 profile、重绘 UI 或跳转登录页
这样避免了“一个 iframe 修改状态,其他 iframe 被动等待轮询”的低效模式。
必须配合 IndexedDB 做持久化兜底,不能只靠内存
Shared Worker 内存中的凭证对象会在浏览器回收时丢失(比如所有 iframe 关闭后 Worker 被终止)。因此:
- 首次登录成功后,Worker 应调用
indexedDB.open()存储加密后的 refresh_token 和元数据(使用 SubtleCrypto 生成页面级密钥派生) - 初始化时优先从 IndexedDB 恢复会话,再尝试静默刷新 access_token
- 所有敏感操作(如 signOut)必须同步清除 IndexedDB 记录,防止 iframe 重启后误用残留凭证
注意:不能用 localStorage —— Shared Worker 无法访问它,且 localStorage 是页面级隔离的。
Safari 和 iOS 需特别处理,兼容性不是可选项
截至 2026 年 5 月,Safari 16.4+ 已支持 Shared Worker,但存在两个现实限制:
- 若 iframe 使用
sandbox属性(常见于第三方嵌入场景),需显式添加allow-scripts allow-same-origin,否则无法创建 SharedWorker 实例 - Safari 对 IndexedDB 在 SharedWorker 中的事务稳定性仍较弱,建议加 fallback:当 indexedDB.open 失败时,退回到内存缓存 + 强制主页面主导登录流程
最后强调一点:Shared Worker 不替代身份认证服务,它只是前端多上下文间“可信代理”。真正的鉴权逻辑(如 scope 校验、token 解析、签名验证)仍应在服务端完成,Worker 只负责安全地传递和同步结果。

















