10

CSRF保護を使用するフォームを含むDjangoビューがあります。通常のGETリクエストがある場合に、このビューをVarnishによってキャッシュしたいと思います(すべてのユーザーが同じフォームを必要とし、ログインは必要ないため)。

したがって、2つの課題があります。

  1. このページをVarnishにキャッシュし、キャッシュされた/古いバージョンのcsrf非表示フィールドをユーザーに配信しない方法は?CSRFフィールドを使用してページをキャッシュすることは可能ですか?

  2. 私のワニスはデフォルトですべてのCookieを削除しますが、csrftoken Cookieを除くすべてのCookieを簡単に削除するにはどうすればよいですか?また、特定のCSRF_COOKIE_DOMAINを設定する必要がありますか?

4

3 に答える 3

9

これは数年遅れていますが、最近この問題を回避した方法を次に示します。

トリックは、ワニスがサポートするESIを使用することです。CSRF スニペットを取得し、ワニスを通過するときは ESI 経由で含め、それ以外の場合 (ローカル開発サーバーを実行するときなど) は直接、それを独自のページに貼り付けます。

csrf_esi.html:

{% csrf_token %}

csrf_token.html

{% if request.META.HTTP_X_VARNISH_USE_CACHE %}
<esi:include src="{% url 'esi_csrf_token' %}" />
{% else %}
{% include "csrf_esi.html" %}
{% endif %}

urls.py

from django.conf.urls import url
from django.views.generic import TemplateView

urlpatterns = [
    ...
    url(r'csrf_esi.html', TemplateView.as_view(template_name="csrf_esi.html"), name='esi_csrf_token'),
]

csrf_esi.py

from django import template

register = template.Library()

@register.inclusion_tag('csrf_token.html', takes_context=True)
def csrf_token_esi(context):
    return context

設定.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            ...
            'builtins': [
                'path.to.csrf_esi',
            ],
        }
    }
]

ワニス構成

set req.http.X-Varnish-Use-Cache = true;

csrf_esi.htmlまた、キャッシュされないようにページをホワイトリストに登録しset beresp.do_esi = true;、関数内に追加する必要がありvcl_fetchます。これについてもっと詳しく説明したいと思いますが、システムのこの部分を設定したわけではなく、100% 明確ではありません。


{% csrf_token %}これで、通常のタグと同じように簡単に使用できます。

<form action="">
    {% csrf_token_esi %}
    <button type="submit">Push me</button>
</form>

セットアップにはかなりの手間がかかりますが、一度セットアップすれば、二度と見る必要はありません。

于 2016-03-21T01:29:31.707 に答える
8

ビューで CSRF を使用することは、基本的に、ビューの各レンダリングが本質的に異なることを意味します (1 つの非表示フィールドの値のみが変更されている場合でも)。このようなシナリオでは、キャッシュは機能しません。

ただし、Django はこの制限を回避するためのメカニズム、つまり Cookie を提供しています。2 つ目のパートでは、次の 2 つのことを行う必要があります。

  1. 非表示フィールドを使用する代わりに、CSRF Coo​​kie を送信するように Django を設定します。(参照: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#s-caching )
  2. Varnish が Django が送信する Cookie を無視するようにします。(参照: http://www.varnish-cache.org/docs/trunk/tutorial/cookies.html )

CSRF_COOKIE_DOMAINリクエストが処理されるドメインとは異なるドメインから送信される場合にのみ、Django で設定する必要があります。

于 2011-06-09T14:29:23.117 に答える
1

@csrf_protect と AJX を使用して同様の問題が発生しました。誰かがこのデコレータを使用している場合、これが役立つ可能性があります

ワニスに例外を追加するだけでなく。フォームのあるビューとデータが投稿されているビューの両方がデコレーターを使用していることを確認してください。

投稿ビューに @csrf_protect しかありませんでしたが、ローカルでのテストはうまくいきましたが、ライブに行ったときに、ページ ビューにデコレータを追加することで 403 検証に失敗するという問題が発生し、これが修正されました。

于 2012-08-29T09:56:24.367 に答える