web-dev-qa-db-ja.com

CSRF失敗:CSRFトークンが欠落しているか、正しくありません

私はDjango 1.7およびDjango-rest-frameworkを使用しています。

これをsettings.pyに入れるJSONデータを返すAPIを作成しました

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
    'DEFAULT_RENDERER_CLASSES': (
    #   'rest_framework.renderers.XMLRenderer',
    'rest_framework.renderers.JSONRenderer',
    #   'rest_framework.renderers.BrowsableAPIRenderer',
    )
}

GET呼び出しを行うと、すべてのデータが返されますが、PUT/PATCHを試すと次のようになります。

--------Response Headers---------
Status Code: 403
Date: Wed, 29 Oct 2014 18:51:42 GMT
Vary: Cookie
Server: WSGIServer/0.1 Python/2.7.8
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
---------------------------------

--------Response Body-----------
{"detail": "CSRF Failed: CSRF token missing or incorrect."}
---------------------------------

これは、ログインしているときにのみ発生します。匿名の場合は、正しくPUT/PATCHできます。

@csrf_exemptを試しましたが、エラーが発生しました。設定にrest_framework.permissions.AllowAnyを含めました...

何が起こっているのか分かりません。誰が問題が何か知っていますか?

37

SessionAuthentication を使用している場合、通常CSRFをチェックする必要があるDjangoの認証を使用しています。 Django RESTフレームワークはSessionAuthenticationに対してのみこれを強制するため、X-CSRFTokenヘッダーでCSRFトークンを渡す必要があります。

Django documentation は、jQueryを使用してCSRFトークンを取得し、リクエストで送信することに関する詳細情報を提供します。 CSRFトークンはcsrftokenというCookieとして保存され、HTTP応答から取得できます。これは、使用されている言語によって異なります。

CSRF Coo​​kieを取得できない場合、これは通常SessionAuthenticationを使用してはならないという兆候です。必要に応じて、 TokenAuthentication または OAuth 2. を調べることをお勧めします。

62
Kevin Brown

これは私がそれを解決するためにしたことです、フォームにcsrfトークンを含め、jquery/javascripを使用すると、ドキュメントがロードされたときにこのようなcsrfトークンを取得しました

var $crf_token = $('[name="csrfmiddlewaretoken"]').attr('value');

次のようにjqueryヘッダーに含まれています

 $.ajax({
            type: "POST",
            url: "/api/endpoint/",
            data: newEndpoint,
            headers:{"X-CSRFToken": $crf_token},
            success: function (newEnd) {
                console.log(newEnd);
                add_end(newEnd);
            },
            error: function () {
                alert("There was an error")
            }
        });
4
adoniswalker

1- Cookieヘッダーの検索

enter image description here

2- csrftokenをsessionidから分離します

3- X-CSRFToken = {.. the 2.で抽出したcsrftokenを追加します。

enter image description here 4-再投稿

3
Feras

私たちはこの問題を抱えていましたが、それはポストマンのせいでした。ヘッダーで渡されなかったcsrftokenおよびsessionidのデフォルト値を自動的に送信していました。このチュートリアルに従うと、問題の修正に役立ちました: https://avilpage.com/2019/02/Django-tips-csrf-token-postman-curl.html

2
Blairg23

同様の問題が発生しました。URLをcsrf_exemptメソッド-

from Django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
2
Suyash Soni
// USING AJAX TO UPDATE DATABASE THROUGH REST API
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});
1
Rajiv Sharma

ビューをcsrf_exemptでラップしても同様の問題が発生しましたが、それでもエラーが発生していました。 URLが間違っていることが判明したため、「見つからない」コールバック(CSRFを免除されていない)に解決されたため、URLが間違っていると通知される前に例外をスローしていました。

1
kokociel

Cookieからトークンを取得します。

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

var csrftoken = readCookie('csrftoken');

ヘッダーでトークンを送信POST request:

  this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
            this.response = response.data;
        },
        function (response) {
            console.log(response);
        });
0
Ruslan

ホストDjango Apacheサーバー上のWebサイト。TokenAuthenticationおよびSessionAuthenticationを使用したDjando restフレームワークは、

CSRF失敗:CSRFトークンが欠落しているか、正しくありません

このオープンApache設定ファイルを修正するには-httpd.conf次の行を追加します。

WSGIPassAuthorization On
0
Rajiv Sharma