Skip to content

Next.js 高级架构

Next.js 如何防止动态数据进入公共缓存造成越权?

缓存安全的核心不是记住一个 no-store,而是证明每一层缓存的 key、生命周期和失效路径都不会跨用户复用。

适合阶段:安全面 / 架构面核心能力:缓存隔离 · 授权 · 失效

面试官想考什么

  • 带 cookie 的页面能不能静态化? 考察动态数据判断。
  • CDN、Next Data Cache 和 Router Cache 如何串起来? 考察多层缓存。
  • 只在页面上做权限判断安全吗? 考察数据层授权。
  • 缓存命中错误如何快速止损? 考察应急治理。

一句话回答

text
先把个性化和公共数据分类,用户/租户/权限相关请求默认不进入共享缓存;授权在数据访问点执行,缓存 key 和响应头明确隔离,发布前用跨用户 E2E 验证,线上准备清缓存和禁用缓存开关。

面试回答详解

1. 数据分类

  • 公共内容:所有用户相同,可 CDN/静态缓存。
  • 租户内容:至少按 tenant 分区,仍要检查成员关系。
  • 用户内容:按 user/session 隔离,通常不共享。
  • 权限计算结果:短生命周期或不缓存,避免角色变更后继续生效。

2. 多层缓存

text
browser/Router Cache -> CDN -> Next Data Cache
-> origin/DB

每层都有自己的 key 和 TTL。Cache-Control: private/no-store、Next 的缓存配置和客户端导航缓存要同时检查,不能只配置其中一层。

3. 授权位置

Proxy 可做早期拦截,页面可以隐藏 UI,但最终授权必须在 Route Handler、Server Action 或 domain service 的数据访问点执行。缓存命中路径也不能绕过授权。

4. 失效策略

角色、租户成员、订单和账单变化后,按资源 tag/revision 失效;必要时让客户端刷新 Router Cache。不能用全局清缓存掩盖 key 设计错误,也不能用长 TTL 缓存权限结果。

5. 验证与应急

自动化测试使用用户 A/B、租户 A/B、首次访问/预取/刷新/客户端导航多种路径检查响应和 RSC。监控 cache hit、auth deny、敏感字段扫描和异常租户访问。怀疑泄露时立即切换 no-store、撤销 URL、清理 CDN 并审计访问。

可直接背诵的 30 秒回答

text
我先按公共、租户、用户和权限结果分类,用户相关数据默认不进共享缓存。每层缓存都明确 key、TTL、响应头和失效方式,授权放在真正读写数据的服务端边界,不依赖 Proxy 或隐藏按钮。上线用跨用户跨租户 E2E 验证,并准备 no-store、清 CDN、撤销链接和审计的应急方案。

扩展知识

安全审查清单

text
谁能看到? -> key 是否区分? -> 哪层会缓存?
多久有效? -> 如何失效? -> 失效失败怎么办?

面试官追问链

追问一:带 Authorization Header 的请求一定不会缓存吗?

  • 考察点:不能凭经验判断。
  • 回答方向:要看框架、代理、响应头和缓存配置,必须用真实部署做验证;敏感请求显式设置 private/no-store 更稳妥。

追问二:为什么改了数据库页面还是旧的?

  • 考察点:失效链路。
  • 回答方向:检查 Data Cache、Full Route Cache、Router Cache、CDN 和 revalidation 是否都更新,确认 mutation 失效的是同一个资源标签。

追问三:如何证明没有跨用户泄露?

  • 考察点:测试设计。
  • 回答方向:隔离 cookie、租户和权限,用代理/CDN 命中场景重复访问并扫描敏感字段,不只测源站直连。

推荐阅读

基于 MIT 协议开源