2017-08-21 2 views
3

Ich habe eine ziemlich komplexe Webanwendung basierend auf Django 1.11. Vor einiger Zeit Benutzer begannen zu berichten, dass sie bekommen "jemand anderen Ansichten" - memcached zur Verfügung gestellt sie mit html im Cache von Dekorator @cache_page(xx) ohne Unterscheidung zwischen den Sitzungen innerhalb der Cache-Frist.Django fehlt Vary: Cookie-Header für zwischengespeicherte Ansichten

Bei weiterer Untersuchung entdeckte ich, dass in einigen Fällen Vary: Cookie Header fehlte und falsche 'Sitzung' serviert wurde. Was seltsam ist, zeigte es nur, wenn Backend mit curl abgefragt wurde (das hat keine Sitzung, Benutzer etc -> Backend gedient, geloggt in der gecachten Ansicht).

Leider ist dieses Problem wirklich schwer zu reproduzieren, manchmal tritt es auf, manchmal nicht. Ich baue sogar eine einfache Django-App von Grund auf neu, um zu sehen, ob ich überprüfen könnte, was die Ursache ist. Was beobachtet wurde, ist, dass das Problem nicht auftritt, wenn @cache_page entfernt oder login_required hinzugefügt wird.

Ich entfernte schließlich alle @ cache_page-Dekoratoren aus den Ansichten und das Problem wurde nicht in der Produktion beobachtet, aber es ist ein Workaround und ich würde gerne wissen, was die Ursache ist.

Wenn jemand irgendeinen Hinweis hat, was die Ursache sein könnte, würde es sehr geschätzt werden!

Antwort

1

Du läufst wahrscheinlich in diese open bug:

Seit Ansicht Dekorateure auf die ausgehende Antwort ausgeführt, bevor Antwort Middleware, die cache_page Dekorateur speichert die Antwort, bevor eine der erwähnten Antwort Middle eine Chance haben, Fügen Sie ihre Vary-Header hinzu. Das bedeutet zwei Dinge: 1) Der verwendete Cacheschlüssel enthält nicht die Header, auf die die Antwort variieren soll, und Django kann diese Antwort später an Benutzer richten, die sie wirklich nicht erhalten sollten, und 2) wenn diese zwischengespeicherte Antwort später ist An einen Benutzer geliefert, enthält es immer noch nicht den Header Vary, den es haben sollte, und kann daher auch falsch von einem Upstream-HTTP-Cache zwischengespeichert werden.

Mit anderen Worten, zu der Zeit, dass die Antwort der SessionMiddleware noch nicht die Möglichkeit, die Vary: Cookie Header gesetzt hatte zwischengespeichert hat, so dass alle Sitzungen den gleichen Cache-Schlüssel zu teilen.

Sie können dies wahrscheinlich umgehen, indem Sie den Header Vary explizit angeben. Zum Beispiel:

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 
+0

Das könnte es sein! Danke für Einsicht. – Brachacz