更新 Varnish ESI 的请求 cookie - 包括来自初始“beresp”的请求

更新 Varnish ESI 的请求 cookie - 包括来自初始“beresp”的请求

我有一个以 Varnish 服务器为前端的应用程序。页面的某些部分使用 ESI 包含项进行呈现。

我的问题是上游响应包含一个加密的会话 cookie,其中除其他外还包含一个 CSRF 令牌(根本没有服务器端会话存储)。

对于初始请求(请求中没有 cookie),ESI 请求将不包含上游服务器的第一个响应设置的 cookie。

我尝试设置req.http.Cookie钩子vcl_deliver,因为它是请求流中唯一可以同时进行读写访问的地方。但是,使用 varnishlog 查看请求发现 ESI 请求不受影响,req并且res不包含 cookie。

我已尽力仔细查阅文档,但没有找到任何有用的东西。

是否可以实现我想要的,即更新req以便 ESI 请求包含初始上游响应返回的 cookie?

答案1

我们需要明确区分包含标头的请求Cookie和包含标头的响应Set-Cookie

假设 CSRF 令牌是通过Set-Cookie父响应的标头设置的,您可能希望通过CookieESI 子请求中的请求标头访问该值。

假设 Cookie 标头已包含 CSRF 令牌

req_top.http.Cookie变量可以访问父请求的 cookie,但是req_top无法在解析vcl_backend_responseESI 占位符的地方访问。

您可以使用以下 VCL 代码片段绕过此限制:

sub vcl_recv {
    if (req.esi_level > 0 ) {
        set req.http.X-Parent-Cookie = req_top.http.Cookie;
    }
}

这将启用通过X-Parent-Cookie可用的标题。vcl_backend_responsebereq.http.X-Parent-Cookie

假设 Cookie 标头尚未包含 CSRF 令牌

可以现实地假设它req_top.http.Cookie尚未包含 CSRF 令牌的值,因为在处理 ESI 子请求时,Cookie客户端尚未设置标头。

我能想到的唯一解决方案是将父Set-Cookie值存储在变量中。Varnish 本身不支持变量,需要官方https://github.com/varnish/varnish-modules待安装。

您必须从源代码进行编译。

https://github.com/varnish/varnish-modules/blob/master/src/vmod_var.vcc获取vmod_varAPI 和代码示例。

相关内容