基于Cookie的清漆响应

问题描述

我具有以下Varnish配置:


# Default backend deFinition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_hash {

    if (req.http.cookie ~ "wordpress_logged_in_[a-z0-9]+") {
        set req.http.X-TMP = regsuball(req.http.cookie,"wordpress_logged_in_[a-z0-9]+=[^;]+(; )?","; \1=");
        hash_data(req.http.X-TMP);
        unset req.http.X-TMP;
  }

}

sub vcl_recv {

    #Admin Area
    if (req.url ~ "wp-admin|wp-login") {
        return (pass);
    }


    #woocommerce specifics
    if (req.url ~ "^/(cart|my-account|checkout|addons)") {
        return (pass);
    }

    if ( req.url ~ "\?add-to-cart=" ) {
        return (pass);
    }


    set req.http.cookie = regsuball(req.http.cookie,"wp-settings-\d+=[^;]+(; )?","");
    set req.http.cookie = regsuball(req.http.cookie,"wp-settings-time-\d+=[^;]+(; )?","wordpress_test_cookie=[^;]+(; )?","");
    #set req.http.cookie = regsuball(req.http.cookie,"; \1=");

    #more woocommerce specifics

    # Unset Cookies except for wordpress admin and WooCommerce pages
    if (!(req.url ~ "(wp-login|wp-admin|cart|my-account/*|wc-api*|checkout|addons|logout|lost-password|product/*)")) {
        unset req.http.cookie;
    }

    # Pass through the WooCommerce dynamic pages
    if (req.url ~ "^/(cart|my-account/*|checkout|wc-api/*|addons|logout|lost-password|product/*)") {
        return (pass);
    }

    # Pass through the WooCommerce add to cart
    if (req.url ~ "\?add-to-cart=" ) {
        return (pass);
    }

    # Pass through the WooCommerce API
    if (req.url ~ "\?wc-api=" ) {
        return (pass);
    }

    if (req.http.cookie == "") {

        unset req.http.cookie;
    }

    return(hash);
}


sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers,removing silly Set-Cookie headers
    # and other mistakes your backend does.

    if (beresp.ttl == 120s) {

        set beresp.ttl = 1h;

    }

    #set beresp.http.host = bereq.http.host;
}

sub vcl_deliver {
    # Happens when we have all the pieces we need,and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}

我的目标是根据用户是否登录来确保URL上有两个不同的缓存版本。我可以通过名为wordpress_logged_in_[some id]的cookie来确定这一点。

我已经尝试在this article中寻找灵感,但是根据客户是否具有前面提到的cookie,我无法获得两个不同的结果。在我看来,无论Cookie是否存在,它看起来都是相同的缓存内容

在帮助理解我的问题方面,我将不胜感激。

解决方法

看起来您在做所有正确的事情,但我建议您进行一些调试。

如果运行以下命令,则Hash标签将出现在varnishlog中:

varnishadm param.set vsl_mask +hash

然后您可以运行以下命令,根据Cookie来检查哈希值是否不同

varnishlog -g request -i requrl -i hash -I reqHeader:Cookie

此日志记录命令列出以下项目:

  • 请求网址
  • cookie标头
  • 创建的哈希

这应该可以帮助您了解发生了什么事情。

,

应用本文中建议的解决方案将产生与登录用户(每用户缓存)一样多的缓存条目。

如果您要为来宾提供一个缓存对象,并为所有已登录用户提供另一个缓存对象,则对基于布尔型cookie设置的“布尔值”进行散列:

sub vcl_hash {
  if (req.http.cookie ~ "wordpress_logged_in_") {
    hash_data("wordpress_logged_in");
  }
  # the builtin.vcl will take care of also varying cache on Host/IP and URL 
}

仅当存在cookie的情况下生成的页面未包含用户特定的内容时,这才是安全的。例如,如果“登录页面”与“退出页面”不同之处仅在于网站标题部分中存在“退出”文本。

任何地方的内容绝对是特定于用户的,您不想应用这样的逻辑。例如,标题文本中的“嗨,约翰”。