【问题标题】:No CDN Cache Hits Ever For Firebase Cloud FunctionsFirebase 云功能没有 CDN 缓存命中
【发布时间】:2022-03-29 11:24:22
【问题描述】:

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

一些相关的细节:

  • 我正在使用 csurf 中间件。
  • 我已经(在选择的端点上)设置了一个缓存控制标头值private, max-age=3600, s-maxage=86400
  • 虽然客户端应用程序要求对用户进行身份验证,但通过设置典型获取请求的选项,对上述端点的请求会省略任何 cookie 和身份验证相关数据,如下所示:
{
  \"method\":\"GET\",
  \"headers\":{
    \"Accept\":\"application/json\",
    \"Content-Type\":\"application/json\"
  },
  \"cache\":\"default\",
  \"credentials\":\"omit\"
}

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

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

我知道 \"vary\" 标头的影响,尽管 Firebase 似乎不允许您从中减去项目 - 只能添加更多内容。

我错过了什么? 蒂亚!

    标签: firebase google-cloud-functions firebase-hosting google-cloud-cdn


    【解决方案1】:

    Firebase 似乎不允许您从中减去项目 - 仅 添加更多。

    这是security by design

    请注意,主机通过以下方式将 Cookie 和授权添加到 Vary 标头 请求动态内容时的默认值。这确保了 您使用的任何会话或 cookie 授权标头都是 缓存键,可防止内容意外泄漏。

    我的猜测是您必须让客户端(或下游服务器)不发送 Cookie 标头。

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

    【讨论】:

    • 是的,它可以防止您意外泄漏数据,但也可以很好地防止它被任何其他用户缓存。在这种情况下,CDN 并不是特别有用。您可以让用户的浏览器缓存来完成这项工作。不过,我认为您正在尝试阻止服务器发送 cookie。我要看看那个。这可能意味着绕过这些特定端点的 csurf 中间件。
    • @TheRealMikeD,如果您只省略中间件,浏览器将继续发送 cookie(它绑定到域 + 路径),这将不起作用。我对谷歌云服务不够熟悉,无法给你更好的建议。理论上,您可以添加另一个更改 VaryCookie 标头的下游缓存。这在野外有效,但我不知道它是否与谷歌服务兼容。
    • 感谢您的评论,@Daniel W。我出城了几天。回来了。我认为您在尝试从请求中消除 cookie 方面处于正确的轨道上。当我从经过身份验证的站点外部发出请求并允许跨站点请求时(我已经为一条路径完成了此操作作为测试),我得到缓存命中。这意味着 cookie 可能是问题所在。我会看看我能做些什么来在获取请求时摆脱它们。
    【解决方案2】:

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

    通过绕过选定端点的 csurf 中间件(返回非敏感、公开可用的数据),不再添加 cookie,因此不再涉及 CDN 的缓存键,这会在 CDN 上为这些端点产生缓存命中。

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 2019-03-18
      • 1970-01-01
      • 2021-10-16
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-28
      相关资源
      最近更新 更多