3

Django 1.11 に基づくかなり複雑な webapp があります。少し前に、ユーザーが「他の誰かのビュー」を取得していると報告し始めました。memcached は@cache_page(xx)、キャッシュ猶予期間内のセッションを区別せずに、デコレーターによってキャッシュされた html をユーザーに提供しました。

さらに調査したところ、場合によってVary: Cookieはヘッダーが欠落しており、間違った「セッション」が提供されていることがわかりました。奇妙なことに、curl を使用してバックエンドにクエリを実行した場合にのみ表示されました (セッション、ユーザーなどがない -> バックエンドがキャッシュされたビューでログに記録されました)。

残念ながら、この問題は再現が非常に難しく、発生する場合と発生しない場合があります。単純な Django アプリをゼロから作成して、原因を確認できるかどうかを確認することさえあります。@cache_page観察されたのは、が削除またはlogin_required追加されたときに問題が発生しないことです。

ビューからすべての @cache_page デコレータを削除することになりましたが、本番環境では問題は観察されませんでしたが、これは回避策であり、原因を知りたいです。

誰かが原因のヒントを持っていれば、それは大歓迎です!

4

1 に答える 1

2

あなたはおそらくこの未解決のバグに遭遇しています:

ビュー デコレーターは応答ミドルウェアの前に最初に発信応答で実行されるためcache_page、前述の応答ミドルウェアのいずれかが Vary ヘッダーを追加する機会を得る前に、デコレーターは応答をキャッシュします。これは次の 2 つのことを意味します: 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
于 2017-08-21T17:29:00.503 に答える