繁体   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