简体   繁体   中英

Varnish response based on Cookie

I have the following Varnish configuration:


# 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+=[^;]+(; )?", "");
    set req.http.cookie = regsuball(req.http.cookie, "wordpress_test_cookie=[^;]+(; )?", "");
    #set req.http.cookie = regsuball(req.http.cookie, "wordpress_logged_in_[a-z0-9]+=[^;]+(; )?", "; \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.
}

My goal is to ensure that I have two different cached versions on URL's based on wether or not the user is logged in. I can determine that by a cookie that is named like wordpress_logged_in_[some id] .

I've attempted to find inspiration for this in this article , but I am unable to get two different results based on whether or not the client has the cookie mentioned before. To me, it appears like it's the same cached content presented regardless of the cookie's presence.

I'd appreciate some help on understanding my issue.

It looks like you're doing all the right things, but I would advise you to do some debugging.

If you run the following command, the Hash tag will appear in varnishlog :

varnishadm param.set vsl_mask +hash

You can then run the following command to check whether or not the hashes differ, based on the cookie

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

This logging command lists the following items:

  • The request URL
  • The cookie header
  • The hash that is created

This should help you figure out what's going on.

Applying the solution that was suggested in the article will yield as many cache entries as there are logged in users (per-user cache).

If you want one cache object for guest and the other for all logged in users, then hash on a "boolean" which is set based of presence of the 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 
}

This will be only safe if in presence of the cookie the generated page doesn't bare user-specific content. For example, if "logged in page" is different from "logged out page" only by the presence of "Log out" text in the header section of the site.

Anywhere the content is absolutely user-specific, you don't want to apply such logic. For example, "Hi, John" in the header text.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM