基于 Cookie 的 Varnish 响应
Varnish response based on 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]+=[^;]+(; )?", "; =");
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]+=[^;]+(; )?", "; =");
#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 上有两个不同的缓存版本。我可以通过名为 [=11] 的 cookie 来确定=].
我试图在 this article 中找到这方面的灵感,但我无法根据客户端是否具有前面提到的 cookie 来获得两个不同的结果。对我来说,无论 cookie 是否存在,都显示相同的缓存内容。
如果能帮助我理解我的问题,我将不胜感激。
看起来你做的一切都是正确的,但我建议你做一些调试。
如果您运行以下命令,Hash
标签将出现在varnishlog
中:
varnishadm param.set vsl_mask +hash
然后您可以运行以下命令根据 cookie
检查哈希值是否不同
varnishlog -g request -i requrl -i hash -I reqHeader:Cookie
此日志记录命令列出了以下项目:
- 要求URL
- cookie header
- 创建的散列
这应该可以帮助您弄清楚发生了什么。
应用文章中建议的解决方案将产生与登录用户一样多的缓存条目(per-user 缓存)。
如果您想要一个缓存 object 用于来宾,另一个用于所有登录用户,则对基于 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 时生成的页面不包含 user-specific 内容,这才是安全的。例如,如果“登录页面”与“注销页面”的不同之处仅在于网站 header 部分中存在“注销”文本。
任何内容绝对是 user-specific 的地方,您不希望应用这样的逻辑。例如,header 文本中的“嗨,约翰”。
我有以下 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]+=[^;]+(; )?", "; =");
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]+=[^;]+(; )?", "; =");
#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 上有两个不同的缓存版本。我可以通过名为 [=11] 的 cookie 来确定=].
我试图在 this article 中找到这方面的灵感,但我无法根据客户端是否具有前面提到的 cookie 来获得两个不同的结果。对我来说,无论 cookie 是否存在,都显示相同的缓存内容。
如果能帮助我理解我的问题,我将不胜感激。
看起来你做的一切都是正确的,但我建议你做一些调试。
如果您运行以下命令,Hash
标签将出现在varnishlog
中:
varnishadm param.set vsl_mask +hash
然后您可以运行以下命令根据 cookie
检查哈希值是否不同varnishlog -g request -i requrl -i hash -I reqHeader:Cookie
此日志记录命令列出了以下项目:
- 要求URL
- cookie header
- 创建的散列
这应该可以帮助您弄清楚发生了什么。
应用文章中建议的解决方案将产生与登录用户一样多的缓存条目(per-user 缓存)。
如果您想要一个缓存 object 用于来宾,另一个用于所有登录用户,则对基于 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 时生成的页面不包含 user-specific 内容,这才是安全的。例如,如果“登录页面”与“注销页面”的不同之处仅在于网站 header 部分中存在“注销”文本。
任何内容绝对是 user-specific 的地方,您不希望应用这样的逻辑。例如,header 文本中的“嗨,约翰”。