Varnish - 分離和附加cookie

Varnish - 分離和附加cookie

首先,我想知道這是否可能。

所以,我可以看到如果 Varnish 有 cookie,它就不會快取物件。

我正在考慮當傳入請求有 cookie 時,Varnish 會將它們儲存在變數中並刪除這些 cookie,然後讓它通過後端。一旦後端處理完成,Varnish 就會放回 cookie。

這是可能的嗎?

如果是的話,vcl 是什麼樣子的?

答案1

情境

Varnish 在快取方面是保守的,並假設 cookie 的使用意味著回應的個人化程度。

快取個人化回應可能會導致隱私或安全問題。它也可能導致輸出不一致。

想像一下快取一個包含購物車的頁面。快取整個頁面將導致每個人都具有相同的購物車價值。

以下是 Varnish 對 cookie 的內建 VCL 行為:

  • 當 Varnish 看到Cookie請求中的標頭時,它不會從快取中提供對象,因為它假設內容是個人化的。

https://www.varnish-software.com/developers/tutorials/varnish-builtin-vcl/#authorization-headers-and-cookies-are-not-cacheable

  • 當 VarnishSet-Cookie在回應中看到標頭時,它不會將物件儲存在快取中,因為設定 cookie 是一種狀態更改,也意味著個人化。

https://www.varnish-software.com/developers/tutorials/varnish-builtin-vcl/#dont-cache-responses-with-set-cookie-headers

剝離餅乾

一旦透過回應標頭設定了 cookie Set-Cookie,它將作為每個後續請求的請求標頭傳遞Cookie,即使對於不真正需要這些 cookie 的頁面也是如此。

這就是為什麼確定哪些頁面需要 cookie,哪些不需要 cookie 很重要。識別追蹤 cookie 同樣重要,因為它們是由客戶端在 Javascript 中處理的,而不是在伺服器上處理的。

這是一個 VCL 範例,其中我們刪除了所有 cookie,除了伺服器上需要的 cookie:

vcl 4.1;

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, ";(PHPSESSID)=", "; \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;
    }
}

在這種情況下,僅PHPSESSID保留 cookie,因為需要它來追蹤登入。如果在替換邏輯之後此 cookie 仍然存在,Varnish 將不會提供來自快取的回應。如果未設定此 cookie,但有一堆追蹤 cookie,則所有 cookie 都會被刪除,並且可以從快取中提供頁面。

刪除某些頁面的 cookie

雖然前面的範例剝離了選定的 cookie 並僅保留PHPSESSIDcookie,但您仍然可能會看到實際上不需要該會話 cookie 的頁面。

下面是一個 VCL 範例,其中 cookie 被完全剝離,除了實際需要特定 cookie 的頁面,例如管理頁面和購物車頁面:

vcl 4.1;

sub vcl_recv {
    if(req.url ~ "^/admin" || req.url == "/cart") {
        return(pass);
    }
    unset req.http.Cookie;
}

刪除 Set-Cookie 標頭

如圖所示https://www.varnish-software.com/developers/tutorials/varnish-builtin-vcl/#dont-cache-responses-with-set-cookie-headers,如果使用標頭,內建 VCL 不會將物件儲存在快取中Set-Cookie,因為這表示狀態變更。

然而,這並不意味著該頁面永遠不會在快取中結束:下一個後端回應可能不會包含標頭Set-Cookie,因為 cookie 已經設定。在這種情況下,沒有標頭的下一個回應Set-Cookie可能會出現在快取中。

但是,如果您確定不需要為某些頁面設定 cookie,您也可以決定刪除Set-Cookie標頭。

以下範例阻止後端為靜態內容設定 cookie:

vcl 4.1;

sub vcl_backend_response {
    if (bereq.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
        unset beresp.http.Set-Cookie;
    }
}

重新附加 cookie

雖然可以將 cookie 值儲存在標頭中,然後在 VCL 中剝離 cookie 以從快取中提供服務,最後重新附加後端請求,但這並沒有多大意義。

如果可緩存回應不需要 cookie 來建立其輸出,為什麼要為後端請求發送 cookie?

如果後端請求需要 cookie 值來組成輸出,則可能表示回應將不可緩存,因此您最好完全繞過該請求的快取。

下一步

因為你的問題不是很具體,所以我也不得不給你一個非常籠統的答案。

如果我的回答完全回答了您的問題,我邀請您指定有關您的用例的更多詳細信息,作為回報,我將為您提供更詳細的答复。

相關內容