在 Varnish Edge-side 中有条件地删除授权 header 包括 (ESI)

Conditionally removing authorization header in Varnish Edge-side includes (ESI)

我使用带有 Edge-side 的 varnish 包括主要端点需要授权的端点,但 ESI 通常不需要...但有时他们需要。我现在通过添加 header 来处理它 当我希望所有 ESI 请求保留授权 header 时,我将 Keep-Authorization 调用到主 请求 .然后我有

vcl_recv {
  ...
  if (req.esi_level > 0 && !req.http.Keep-Authorization) {
    unset req.http.authorization;
  ...
  }
}

这可以正常工作,但非常不优雅——它要求请求者知道是否添加 Keep-Authorization header。虽然 API 目前仅供我们使用,但可能会改变。

事实上,0 级响应知道其 ESI children 是否需要授权,并且应该能够设置 header 来表明这一点。如果我可以在清漆生命周期的适当部分阅读它,我可以在根据我从 0 级响应中获得的内容解决 ESI 之前适当地删除(或不删除)授权 header。

这似乎是我在 vcl_backend_response 中必须做的事情,但我不太确定。或者,如果在 vcl_recv 中有类似 req_top 的顶级响应(在解决 ESI 时应该可用)也可以解决问题。

简而言之,我希望源能够确定是否保留授权 header 以在其响应中解析 ESI。这可行吗?

不幸的是,没有 beresp_top 这样的东西。并且因为客户端逻辑和后端逻辑在 VCL 中分开,所以在 vcl_recv 中使用原生 VCL 确实可以获取该信息。

一个可能的解决方案是利用 vmod_var。这是 https://github.com/varnish/varnish-modules.

的一部分的开源 Varnish 模块

目前没有它的包,所以你必须从源代码编译它。根据 Varnish 的版本,您需要下载正确的分支。

var.global_set() function allows you to set a global variable in vcl_backend_response, which you can retrieve in vcl_recv using var.global_get()

然后您可以使用以下 VCL 代码有条件地剥离 Authorization header:

vcl 4.1;

import var;

sub vcl_recv {
    if(var.global_get(req.url + "-remove-auth") == "true" || var.global_get(req_top.url + "-remove-auth") == "true") {
        unset req.http.Authorization;
    }
}

sub vcl_backend_response {
    if(beresp.http.X-Remove-Auth) {
        var.global_set(bereq.url + "-remove-auth", "true");
    }
}