Django缺少Vary:缓存视图的Cookie标头

时间:2017-08-21 09:04:03

标签: python django caching memcached vary

我有一个基于Django 1.11的非常复杂的webapp。 前段时间,用户开始报告他们正在获取其他人的观点' - memcached为它们提供了由装饰器@cache_page(xx)缓存的html,而不区分缓存宽限期内的会话。

经过进一步调查,我发现在某些情况下,Vary: Cookie标题丢失,错误的“会话”#39;送达了。有什么奇怪的,它只在用curl查询后端时显示(没有会话,用户等 - >后端服务登录缓存视图)。

不幸的是,这个问题很难重现,有时它会发生,有时它并不存在。我甚至从头开始构建一个简单的Django应用程序,看看我是否可以检查是什么原因。 观察到的是,删除@cache_page或添加login_required时不会出现此问题。

我最终从视图中删除了所有@cache_page装饰器,但是在生产中没有发现问题,但它是一种解决方法,我想知道原因是什么。

如果有人有任何暗示可能是什么原因,我们将不胜感激!

1 个答案:

答案 0 :(得分:2)

你可能遇到了这个open 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
相关问题