【问题标题】:Django missing Vary:Cookie header for cached viewsDjango 缺少缓存视图的 Vary:Cookie 标头
【发布时间】:2017-08-21 09:04:02
【问题描述】:

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

经过进一步调查,我发现在某些情况下Vary: Cookie 标头丢失并且提供了错误的“会话”。奇怪的是,它只在使用 curl 查询后端时显示(没有会话、用户等 -> 后端服务登录在缓存视图中)。

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

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

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

【问题讨论】:

    标签: python django caching memcached vary


    【解决方案1】:

    你可能遇到了这个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
    

    【讨论】:

    • 这可能是它!感谢您的洞察力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 2013-02-13
    • 2013-08-18
    • 2011-12-22
    • 2013-08-19
    • 1970-01-01
    • 2014-03-19
    相关资源
    最近更新 更多