题目与场景
一个身份服务商被嵌入许多客户网站的 iframe。已登录用户应看到账户信息,但浏览器可能分区或阻止第三方 Cookie。请使用 Storage Access API 设计流程,同时避免把每个嵌入组件变成静默追踪通道。
假设 iframe 可以导航到身份服务自己的第一方页面,顶层网站控制 iframe 权限,用户也可能拒绝提示。回答需覆盖同意、CSRF、降级和登出。
面试官考察什么
- 是否知道存储访问受权限和 iframe 上下文限制,不是万能 Cookie 开关。
- 是否要求用户激活,并在请求前解释明确的产品用途。
- 能否分离分区引导状态和未分区会话状态。
- 拒绝后是否仍能提供已登出或重定向登录路径。
作答前的澄清问题
- 组件是否必须跨站保持会话,还是可以重定向后返回授权码?重定向可能无需请求嵌入式 Cookie 访问。
- 用户是否曾以第一方访问身份服务并设置 Cookie?部分浏览器在授予访问前要求这种关系。
- 哪些顶层 origin 可以嵌入 iframe?这决定
Permissions-Policy白名单。 - 同意前能显示什么数据?预授权界面不能泄露账户身份。
30 秒回答框架
“我把 Storage Access API 当作由用户授权的能力,不当作 Cookie 开关。iframe 先使用分区或不透明状态,只有用户点击并理解收益后才请求,并处理 Promise 拒绝。顶层网站提供狭窄的 Permissions-Policy 白名单。拒绝时走第一方重定向或已登出体验。所有状态变更请求仍需要 CSRF 防护,登出后组件回到同一中性状态。”
分步骤深入解答
1. 分离状态与威胁模型
授权前,iframe 可能只有分区存储或没有 Cookie,不能据此推断用户身份。requestStorageAccess() 成功后,嵌入文档才可能按浏览器策略访问未分区第一方 Cookie。
该能力限定在文档和嵌入上下文中。它不证明顶层网站可信,也不能替代 origin 校验、CSRF 防护、同意记录和登出语义。
2. 用用户意图触发请求
先渲染匿名组件,只显示“登录后查看账户信息”按钮。按钮点击形成用户激活,在处理器中调用 API,并把拒绝当成正常分支。不要页面加载时请求,也不要用隐藏 iframe 制造激活。
应用应说明哪些数据会变得可用,并只在浏览器政策允许时记住选择。拒绝可能来自第三方 Cookie 被阻止、用户没有第一方访问、iframe 缺少策略许可,或上下文不满足条件。
3. 配置嵌入边界
顶层响应负责策略。只允许身份 origin,并且只在嵌入组件的路由上允许:
Permissions-Policy: storage-access=(self "https://id.example")iframe 必须使用预期 origin 和 sandbox 设置。被 sandbox 的 iframe 需要保留合适的同源能力,origin 不匹配时应默认拒绝。策略应是白名单,不是给所有第三方授权。
4. 建立第一方与嵌入流程
如果浏览器要求第一方交互,组件打开身份服务的第一方页面。用户在那里登录,身份服务设置第一方 Cookie,再返回与 origin 绑定的短期结果。结果不应是 URL 中可重复使用的 bearer token。
回到 iframe 后,在用户手势下请求存储访问,再通过身份 origin 读取会话。服务端仍检查顶层 origin、会话状态和 CSRF token。授权成功不等于绕过账户权限。
5. 设计拒绝、登出与度量
拒绝时保持组件可用:显示登录链接、使用重定向返回,或提供第一方账户页。不要循环弹提示。登出要清理身份会话并把 iframe 恢复到中性状态,同时使缓存的账户视图失效。
按浏览器和嵌入 origin 衡量授权成功、拒绝原因、重定向完成和账户视图错误,但绝不记录 Cookie 或账户数据。即使以后移除 Storage Access API 路径,重定向流程仍应可用。
高质量示范回答
我会先让匿名 iframe 只显示登录入口。用户点击后请求存储访问,并明确处理拒绝。嵌入页面通过 Permissions-Policy 只允许身份 origin。如果浏览器要求第一方交互,就重定向到身份站点建立会话,再返回与 origin 绑定的短期结果,不把 bearer token 放进 URL。
授权后 iframe 可以读取第一方会话,但仍要执行 origin 校验、CSRF 防护、授权和登出。拒绝时走重定向登录或已登出视图,绝不重复弹提示。我会按浏览器和 origin 监控授权、拒绝、重定向完成与错误,并保证降级路径可用。
常见失误
- 错误表现:页面加载就调用 API → 失败原因:浏览器要求用户意图,用户也无法理解突然出现的提示 → 修正方法:仅在解释用途后的用户激活中请求。
- 错误表现:把成功当成全局 Cookie 权限 → 失败原因:权限受上下文、策略和浏览器差异限制 → 修正方法:每个嵌入上下文都检查 Promise。
- 错误表现:在
Permissions-Policy中允许所有 origin → 失败原因:扩大追踪和数据访问面 → 修正方法:只在指定路由白名单允许身份 origin。 - 错误表现:把会话 token 放进重定向 URL → 失败原因:URL 会进入历史、日志和 referrer → 修正方法:使用短期、一次性、与 origin 绑定的结果。
- 错误表现:拒绝后继续弹提示 → 失败原因:形成敌对循环,也无法强迫用户授权 → 修正方法:切换到重定向或已登出降级。
追问与回答
分区 Cookie 能替代 Storage Access API 吗?
它可以支持按嵌入站点隔离的引导会话,但不能提供与未分区第一方会话相同的跨站连续性。能接受隔离时选择分区状态;需要连续登录且不想请求访问时选择重定向。
iframe 被 sandbox 怎么办?
确认 sandbox 保留流程需要的 origin 和能力。如果 origin 变成不透明或 API 被阻止,就默认拒绝并使用第一方重定向。不要为了一个组件全局削弱 sandbox。
获得存储访问后还需要 CSRF 防护吗?
需要。获得访问后 iframe 可以携带 Cookie 发送请求,因此状态变更接口仍需要 CSRF 防护、origin 校验、适用时的 SameSite Cookie 和授权。存储权限改变可达性,不改变请求意图。