背景与问题第三方 Cookie 逐步受限,跨站 iframe 的会话与登录变得不可用或不稳定。Storage Access API 允许在用户明确同意下,为特定嵌入场景开启受限存储访问以完成登录。适用场景与限制仅在跨站嵌入(`<iframe src>` 与顶级不同站点)时相关;顶级同站点不需要。需用户手势触发授权;Safari ITP 对交互历史与顶级访问有额外约束。检测与请求流程async function ensureStorageAccess(): Promise<{ ok: boolean; granted?: boolean; reason?: string }> { const has = (document as any).hasStorageAccess ? await (document as any).hasStorageAccess() : true; if (has) return { ok: true, granted: true }; // 显示按钮,由用户点击触发 const btn = document.getElementById('grant-storage-access') as HTMLButtonElement | null; btn?.removeAttribute('hidden'); return { ok: true, granted: false }; } async function onGrantClick() { if ((document as any).requestStorageAccess) { try { await (document as any).requestStorageAccess(); return { ok: true, granted: true }; } catch (e) { return { ok: false, reason: String(e) }; } } return { ok: false, reason: 'unsupported' }; } 登录整合示例async function tryEmbeddedLogin() { const access = await ensureStorageAccess(); if (!access.granted) return { ok: false, reason: 'need-user-gesture' }; const res = await fetch('/api/session', { credentials: 'include' }); if (!res.ok) return { ok: false, reason: 'session-failed' }; const me = await res.json(); return { ok: true, user: me }; } 隐私与合规明确告知用途:仅用于登录/会话恢复,不进行跨站追踪;提供可撤销入口。最小权限:仅在需要时提示;避免在未嵌入或顶级场景误触发。记录结果:仅统计授权成功/取消/失败次数与原因,不记录用户隐私数据。验证指标(Chrome 128/Safari 17,实际嵌入场景)授权成功率:≥ 92%(有清晰文案与交互历史)。登录恢复成功率:≥ 98%(授权后 session 请求成功)。用户拒绝占比:≤ 6%;重复提示率:≤ 1%(每会话仅一次)。失败原因分布:无交互历史/策略限制 ≥ 70% 的失败样本。回退与兼容方案顶级登录跳转:在顶级窗口打开同站点登录页完成登录后返回嵌入页。消息桥:通过 `postMessage` 将顶级窗口的登录状态同步给 iframe。无支持环境:明确提示受限与替代流程,避免无效反复请求。测试清单嵌入首次访问:按钮显隐与授权流程正确;无支持环境提示。授权后会话恢复:`credentials: 'include'` 请求成功,Cookie 可用。策略影响:Safari ITP 与隐私设置下的不同路径均有合理结果。应用场景跨站嵌入客服/支付/账户模块;统一登录托管页面在多站点的安全集成。

发表评论 取消回复