簡體   English   中英

Django缺少Vary:緩存視圖的Cookie標頭

[英]Django missing Vary:Cookie header for cached views

我有一個基於Django 1.11的非常復雜的webapp。 前段時間用戶開始報告他們正在獲取“其他人的觀點” - memcached為他們提供了由裝飾者@cache_page(xx)緩存的html,而沒有區分緩存寬限期內的會話。

經過進一步調查,我發現在某些情況下, Vary: Cookie標頭丟失,錯誤的“會話”被提供。 奇怪的是,它僅在使用curl查詢后端時顯示(沒有會話,用戶等 - >后端服務登錄緩存視圖)。

不幸的是,這個問題很難重現,有時它會發生,有時則不會。 我甚至從頭開始構建一個簡單的Django應用程序,看看我是否可以檢查是什么原因。 觀察到的是,刪除@cache_page或添加login_required時不會發生此問題。

我最終從視圖中刪除了所有@cache_page裝飾器,並且在生產中沒有觀察到問題,但這是一種解決方法,我想知道原因是什么。

如果有人有任何暗示可能是什么原因,將不勝感激!

你可能遇到這個開放的bug

由於視圖裝飾器首先在傳出響應上運行,在響應中間件之前, cache_page裝飾器在任何提到的響應中間件有機會添加其Vary頭之前緩存響應。 這意味着兩件事:1)使用的緩存密鑰不包括響應應該變化的標頭,Django可能稍后將響應提供給真正不應該獲得它的用戶,以及2)當緩存的響應稍后時服務於用戶,它仍然不包括它應該具有的Vary頭,因此也可能被上游HTTP緩存錯誤地緩存。

換句話說,在緩存響應時, SessionMiddleware還沒有機會設置Vary: Cookie標頭,因此所有會話將共享相同的緩存鍵。

您可以通過顯式指定Vary標頭來解決此問題。 例如:

from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie

@cache_page()
@vary_on_cookie()
def my_view():
    pass

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM