Сделать варни sh обслуживать запрос из кеша (куки очищаются) - PullRequest
0 голосов
/ 14 апреля 2020

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-54516992-1"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'UA-54516992-1');
    </script>

</head>
<body>
    test
</body>
</html>

Backend. Это Python + Django. Пожалуйста, не бойся. Я просто установил повара ie здесь (render_to_response), а затем мне нужно место для остановки на точке останова (ниже в коде это показано комментарием, где это).

class HomeView(TemplateView):
    template_name = "home/home.html"

    def render_to_response(self, context, **response_kwargs):
        response = super(TemplateView, self).render_to_response(context, **response_kwargs)
        response.set_cookie('sort_on', 'title')
        return response

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context # Breakpoint.

varnishd В целях обучения я просто очищаю все куки.

$ varnishd -V
varnishd (varnish-6.0.6 revision 29a1a8243dbef3d973aec28dc90403188c1dc8e7)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2019 Varnish Software AS

VCL

vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
    call remove_proprietary_cookies;

    if (req.http.Cookie) {      
        return (pass);
    }

}   


sub remove_proprietary_cookies{
    set req.http.Cookie = regsuball(req.http.Cookie, ".*", "");
}

Затем я несколько раз перезагружаю страницу для готовить ie, чтобы быть определенно там.

В Chrome:

document.cookie
"sort_on=title; _ga=GA1.1.988164671.1586849704; _gid=GA1.1.995393496.1586849704; _gat_gtag_UA_54516992_1=1"

Изображение файлов cookie (дубликаты текста выше):

enter image description here

ОК. Мы проверили, что Cook ie установлен. Теперь давайте проверим, что повар ie очищен должным образом.

Я останавливаюсь у точки и проверяю повар ie. Значение: {}.

enter image description here

Скважина. Кажется, что все куки очищены.

Проблема: При перезагрузке я постоянно подхожу к точке останова. Это означает, что Varni sh передает запрос бэкэнду. Другими словами if (req.http.Cook ie) не работает, как я ожидал. Я ожидаю, что на предыдущем этапе я удалил куки. Затем я проверяю, существуют ли файлы cookie. И не должно быть никаких.

Не могли бы вы мне помочь:

  1. Понять, что здесь происходит.

  2. Организовать все так, чтобы я определенно удалить куки, если я удалил их неправильно.

  3. Заставить Varni sh обслуживать этот запрос из кэша, не передавая его бэкэнду.

========= ===== ДОБАВЛЕНО 16 АПРЕЛЯ ================= +++++++++++++++++++++++ ++++++++++++++++++++++++++++++

Я обновил Varni sh до 6.4:

michael@michael:~$ varnishd -V
varnishd (varnish-6.4.0 revision 13f137934ec1cf14af66baf7896311115ee35598)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2020 Varnish Software AS

Что мы собираемся протестировать:

  1. Установить куки Google Analytics и повара ie на бэкэнде.
  2. Let Varni sh удалите все куки и кэшируйте ответ.
  3. Убедитесь, что запрос передан бэкэнду только один раз.

Затем я организовал nginx позади Varni sh (только для журнал запросов). Nginx прослушивает 8090. Это конфигурация журнала:

   log_format  main  '[$time_local] $http_cookie';

Файлы cookie:

  1. В HTML Я организую отслеживание Google Analytics.
  2. В бэкэнд, который я установил cook ie под названием "sort_on" со значением "title".

+++++++++++++++++++++++ ++++++++++++++++++++++++++++++++

Если мы не режем печенье , журнал выглядит так (это только для СРАВНЕНИЯ):

127.0.0.1 - - [16/Apr/2020:08:11:05 +0300] "GET / HTTP/1.1" sort_on=title; _ga=GA1.1.236170900.1587013419; _gid=GA1.1.2033785209.1587013419 200 334 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36" "127.0.0.1"

++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++

varni sh .ctl

vcl 4.1;
import cookie;

backend default {
    .host = "127.0.0.1";
    .port = "8090";
}


sub vcl_recv {
    unset req.http.Cookie;
    if (req.http.Cookie) {  
        return (pass);
    }   
}

Nginx передает запросы бэкэнду. Бэкэнд находится на порте 8080.

Короче, что слушает где:

Varnish - 8000
Nginx - 8090
Backend - 8080

Запустите varnishd:

michael@michael:~$ sudo varnishd -f /home/michael/PycharmProjects/varnish/varnish.vcl -a localhost:8000

Откройте Chrome, загрузите страницу несколько раз:

enter image description here

Nginx Журнал доступа:

127.0.0.1 - - [16/Apr/2020:08:12:49 +0300] "GET / HTTP/1.1" - 200 334 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36" "127.0.0.1"
127.0.0.1 - - [16/Apr/2020:08:13:21 +0300] "GET / HTTP/1.1" - 200 334 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36" "127.0.0.1"

Мы видим, что повар ie отсутствует. Все хорошо. Файлы cookie отключаются.

Проблема: Запросы неизбежно передаются на серверную часть. Я всегда останавливаюсь на точке останова.

enter image description here

Будете ли вы любезны дать мне совет о том, как справиться с проблемой?

1 Ответ

2 голосов
/ 14 апреля 2020

Varni sh не просматривает содержимое заголовка запроса Cookie, а скорее проверяет, присутствует ли заголовок.

Что вам нужно сделать, это проверить, является ли Cookie заголовок пуст, и если это так, просто удалите все.

Просто добавьте это после вашего regsub оператора:

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

Сделайте процесс немного более гибким

На самом деле вы, вероятно, удалите не все файлы cookie, а только те, которые не являются необходимыми для вашего приложения.

Вы можете использовать это заявление для удаления всех файлов 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, 
        ";(SESS[a-z0-9]+|NO_CACHE)=", "; \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;
    }
    else {
      return (pass);
    }
  }
}

Этот фрагмент удалит все куки, ожидайте, что те, которые соответствуют SESS[a-z0-9]+|NO_CACHE регулярному выражению.

Использование vmod_cookie

Существует более чистый способ подход к замене cook ie в Varni sh и включает использование модуля vmod_cookie в Varni sh. Вы можете найти его здесь: https://github.com/varnishcache/varnish-cache/tree/master/lib/libvmod_cookie

Если вы обновитесь до Varni sh версии 6.4 , vmod_cookie станет частью ядра Varni sh установка.

Это эквивалентно использованию vmod_cookie:

vcl 4.1;
import cookie;

sub vcl_recv {
    cookie.parse(req.http.cookie);
    cookie.keep_re("SESS[a-z0-9]+,NO_CACHE");
    set req.http.cookie = cookie.get_string();
    if (req.http.cookie ~ "^\s*$") {
        unset req.http.cookie;
    }
}
...