10

SOでこれについて多くのことを見てきましたが、何も問題を解決できません。

問題:

CSRF ミドルウェアを有効にすると、Django は AJAX フォーム リクエストに対して 403 で応答し、次のように述べます。

「CSRF Coo​​kie が設定されていません。」

ドキュメントに従って、カスタムの「X-CSRFToken」ヘッダーを設定する JS 機能が実装されました。

期待どおりに動作し、ブラウザーから「csrftoken」 Cookie を取得し、AJAX 要求と共に投稿します。

x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2

しかし、応答はまだ 403 です。

試した解決策:

具体的には、SOまたはWebで見つけることができるすべてを試しました:

  • ミドルウェアが有効になっていることを確認します。

    MIDDLEWARE_CLASSES = [
        ...
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        ...
    ]
    
  • Cookie が有効になっているさまざまなブラウザー。

  • @ensure_csrf_cookieビューを;で装飾する

  • {% csrf_token %}私のテンプレートでの設定;

  • render正しいリクエスト コンテキストを取得するショートカットを使用します。

  • カスタムの設定CSRF_COOKIE_NAMECSRF_HEADER_NAME私のsettings.py;

  • 明示的に設定CSRF_COOKIE_SECURE = FalseしてCSRF_COOKIE_HTTPONLY = False;

  • 明示的に設定CSRF_TRUSTED_ORIGINSする。

  • 開発サーバーと本番サーバーでのテスト。

  • request.META["CSRF_COOKIE_USED"] = True誰かが示唆したように、私の見解でも。

それでも何も得られませんでした。

ヘッダー:

@csrf_exemptprint(request.META)見解では、カスタムヘッダー"X-CSRFToken"がリクエストに存在し、Django のドキュメントに従ってフォーマットされ、"HTTP_" プレフィックスが付けられ、ハイフンがアンダースコアに置き換えられ、すべて大文字の"HTTP_X_CSRFTOKEN"であることは明らかです。

さらに、その値は Django によって設定された Cookie と一致します。

クッキー:

奇妙なことにprint(request.COOKIES)、私のビューでページとフォームの読み込み時に「csrftoken」 Cookieが表示されますが、辞書はAJAXリクエストで空です。それが問題になる可能性はありますか?

実際に何が間違っているのかを見つけようと必死です。これを読んでくれてありがとう。

4

1 に答える 1

7

OK、問題は非常に単純です。

デフォルトでは、Fetch API は資格情報を送信しません。MDNによると:

Request インターフェイスの資格情報の読み取り専用プロパティは、クロスオリジン要求の場合に、ユーザー エージェントが他のドメインから Cookie を送信する必要があるかどうかを示します。これは XHR の withCredentials フラグに似ていますが、3 つの使用可能な値があります。

デフォルトはomitで、Cookie は送信されません。関数の引数に追加same-originするだけです。fetch()

fetch(formUrl, {
    ...
    credentials: 'same-origin',
    ...
})

そして、あなたは行く準備ができているでしょう:)

于 2016-03-08T14:26:05.010 に答える