Firebase Cloud Functions 从来没有 CDN 缓存命中

No CDN Cache Hits Ever For Firebase Cloud Functions

我有一个 REST API 是我用 Firebase Cloud Functions 构建的。无论我尝试什么,我都无法从 CDN 缓存中获取任何端点。

一些相关的细节:

{
  "method":"GET",
  "headers":{
    "Accept":"application/json",
    "Content-Type":"application/json"
  },
  "cache":"default",
  "credentials":"omit"
}

无论我从不同的浏览器(或 Postman)发出多少次相同的请求,我都没有得到任何 CDN 缓存命中。响应 header 通常如下所示:

accept-ranges: bytes
cache-control: private, max-age=3600, s-maxage=86400
content-encoding: gzip
content-type: application/json; charset=utf-8
date: Tue, 22 Mar 2022 20:23:18 GMT
etag: W/"410-SrNPDF/58eInOtNbbyxn6XXXXXXX"
expires: Tue, 22 Mar 2022 20:23:17 GMT
function-execution-id: XXXXXXXXXXXX
server: Google Frontend
set-cookie: _csrf=emL-XXXXXXXXXXXXXXXXXXXX; Path=/
set-cookie: XSRF-TOKEN=H3sVcdDA-XXXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/
strict-transport-security: max-age=31556926
vary: cookie,need-authorization, x-fh-requested-host, accept-encoding
x-cache: MISS
x-cache-hits: 0
x-cloud-trace-context: b50952340f930d74ebfbebXXXXXXXXXX;o=1
x-country-code: US
x-orig-accept-language: en-US,en;q=0.9
x-powered-by: Express
x-served-by: cache-lax10660-LGB
x-timer: S1647980596.749133,VS0,VE2278

我知道“变化”的影响 header,尽管 Firebase 似乎不允许您从中减去项目 - 只能添加更多项目。

我错过了什么? TIA!

Firebase doesn't seem to allow you to subtract items from it - only to add more to it.

这是security by design:

Note that Hosting adds Cookie and Authorization to the Vary header by default when a request is made for dynamic content. This ensures that any session or cookie authorization header you use is made part of the cache key, which prevents accidental leaks of content.

我猜你必须让客户端(或下游服务器)不发送 Cookie header。

您可以通过将 public 部分移动到另一个路径或域来实现。但也许还有一个 Firebase 选项可以在某处打勾,将内容标记为静态而不是动态。

好的,我让它工作了。 @Daniel W. 的回答让我朝着正确的方向思考。问题是我正在使用的 csurf 中间件不断向响应中添加 cookie,而 CDN 正在使用这些作为缓存键,因为在“Vary”header 中包含了“cookie”(Firebase 不会允许您删除)。基本上,这意味着永远不会有任何 CDN 命中,因为每次响应时 csurf 中间件都会更改 cookie。

通过绕过选定端点的 csurf 中间件(return non-sensitive,公开可用数据),不再添加 cookie,因此不再涉及 CDN 的缓存密钥,这为这些端点在 CDN 上产生缓存命中。

您还需要确保不要随请求发送任何 cookie。正如我在原始问题中指出的那样,您可以通过设置 "credentials":"omit" fetch() 调用的配置选项中的选项。请求中没有 cookie,响应中也没有 cookie - 这是关键。

对于任何其他考虑使用此技术的人,请谨慎使用。 @Daniel W. 引用 Firebase 文档是正确的,该文档指出设计是使用 cookie 作为缓存键的一部分。这样做可以确保不暴露敏感数据。所以如果你走这条路,你应该确定你 绕过不暴露任何敏感数据的端点的所有 cookie。请记住,如果给定端点的数据缓存在 CDN 上,则对该端点的任何给定请求都可能在 CDN 上获得缓存命中,并且不会返回到源服务器以进行任何类型的身份验证或验证。

但是,如果您有一个端点,其中 return 的数据不需要身份验证,这将使其可缓存在 Google 云 CDN 服务器上。