首页 > 解决方案 > 如何防止cookie被删除

问题描述

if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
   return (pass);
}

if (req.http.Cookie) {
  set req.http.Cookie = ";" + req.http.Cookie;
  set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
  set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products)=", "; \1=");
  set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

  if (req.http.Cookie == "") {
    unset req.http.Cookie;
  }
}

我需要防止第一个 cookie 被删除,我注意到 varnish 出于某种原因不断删除我所有的 cookie,所以我想知道到底发生了什么,所以我检查了一下,我认为后一部分有问题,我也是需要通过执行以下操作来防止发生设置和取消设置?

if (req.http.Cookie !~ "(^|;\s*)(province=(.*?))(;|$)") {
   return (pass);
}

if (req.http.Cookie) {
  set req.http.Cookie = ";" + req.http.Cookie;
  set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
  set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed-products|province)=", "; \1=");
  set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

  if (req.http.Cookie == "") {
    unset req.http.Cookie;
  }
}

标签: varnish

解决方案


这是我将在您的情况下使用的代码段,以防止删除以下 cookie:

  • 所有组
  • 查看产品
sub vcl_recv {
    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(allgroups|viewed\-products|province)=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
    
        if (req.http.cookie ~ "^\s*$") {
            unset req.http.cookie;
        }
    }
}

最后,在所有 cookie 替换发生并且 cookie 只是空白字符的集合之后,或者如果 cookie 是一个空字符串,我们删除整个 cookie 标头。

当然,如果存在上述任何 cookie,则情况并非如此。

那应该真的可以解决问题。然而,我看到很多关于这种方法的困惑,这是理所当然的,因为这些正则表达式替换很丑陋且难以解释。

vmod_cookie

另一种方法是使用vmod_cookie和利用它提供的干净的 cookie 管理 API。有关文档,请参阅http://varnish-cache.org/docs/6.6/reference/vmod_cookie.html

vmod_cookie是版本的原生 Varnish VMOD 6.4。这意味着版本6.46.56.6默认发布。如果您使用的是旧版本,则可以使用https://github.com/varnish/varnish-modules从源代码编译模块

这是您在案例中使用它的方式:

import cookie;

sub vcl_recv {
    if (req.http.Cookie) {
        cookie.parse(req.http.cookie);
        cookie.keep("allgroups,view-products,province");
        set req.http.cookie = cookie.get_string();

        if (req.http.cookie ~ "^\s*$") {
            unset req.http.cookie;
        }
    }
}

看看什么最适合你,但你必须承认它比调用vmod_cookie更容易使用和理解。regsub()


推荐阅读