webentwicklung-frage-antwort-db.com.de

CSRF fehlgeschlagen: CSRF-Token fehlt oder ist falsch

Ich benutze Django 1.7 und Django-Rest-Framework.

Ich habe eine API erstellt, die mir einige JSON-Daten zurückgibt, die in meinen settings.py eingefügt werden.

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

Wenn ich GET-Anrufe mache, werden mir alle Daten zurückgegeben, aber wenn ich mit PUT/PATCH versuche, bekomme ich:

--------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."}
---------------------------------

Dies passiert nur, wenn ich angemeldet bin. Wenn ich anonym bin, kann ich dies richtig machen.

Ich habe es mit @csrf_exempt probiert und habe Fehler bekommen, ich habe den rest_framework.permissions.AllowAny in die Einstellung aufgenommen ...

Ich habe keine Ahnung, was los ist. Weiß jemand, worum es geht?

32

Wenn Sie SessionAuthentication verwenden, verwenden Sie die Authentifizierung von Django, für die normalerweise CSRF überprüft werden muss. Django REST Framework erzwingt dies nur für SessionAuthentication, daher müssen Sie das CSRF-Token im X-CSRFToken-Header übergeben.

Die Django-Dokumentation enthält weitere Informationen zum Abrufen des CSRF-Token mit jQuery und zum Senden in Anforderungen. Das CSRF-Token wird als Cookie mit dem Namen csrftoken gespeichert, das Sie aus einer HTTP-Antwort abrufen können. Diese hängt von der verwendeten Sprache ab.

Wenn Sie das CSRF-Cookie nicht abrufen können, ist dies normalerweise ein Zeichen dafür, dass Sie SessionAuthentication nicht verwenden sollten. Ich empfehle, in TokenAuthentication oder OAuth 2.0 nach Ihren Bedürfnissen zu suchen.

53
Kevin Brown

Dies ist, was ich tat, um es zu lösen, ich fügte Csrf-Token in das Formular und mit Jquery/Javascrip bekam das Csrf-Token so, wenn das Dokument geladen wurde

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

die enthaltenen JQuery-Header sind wie folgt

 $.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

Wir hatten dieses Problem und es stellte sich heraus, dass Postman schuld war. Sie haben automatisch csrftoken und sessionid Standardwerte gesendet, die wir nicht im Header übergeben haben. Das Befolgen dieses Tutorials hat zur Behebung des Problems beigetragen: https://avilpage.com/2019/02/Django-tips-csrf-token-postman-curl.html

2
Blairg23

Ich hatte ein ähnliches Problem. Ich habe meine URLs unter der csrf_exempt-Methode als 

from Django.views.decorators.csrf import csrf_exempt

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
2
Suyash Soni

Token vom Cookie erhalten:

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');

Token in Kopfzeilen senden POST - Anforderung:

  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
// 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);
        }
    }
});
0
Rajiv Sharma

Ich hatte ein ähnliches Problem, als ich die Ansichten mit csrf_exempt eingepackt hatte und immer noch auf Fehler stieß. Es stellte sich heraus, dass die URL falsch war. Daher wurde sie in einen "nicht gefundenen" Callback aufgelöst (der nicht von CSRF ausgenommen war). Daher wurde eine Ausnahme ausgelöst, bevor mir mitgeteilt wurde, dass die URL falsch war.

0
kokociel

1- Suchen Sie nach dem Cookie-Header

 enter image description here

2- Trennen Sie das csrftoken von der Session-ID

3- Fügen Sie das X-CSRFToken = {.. das in Schritt 2 extrahierte csrftoken hinzu.} Siehe unten

 enter image description here 4- Post noch einmal

0
Feras

Wenn Sie die Django-Website auf dem Apache-Server hosten, wird Djando Rest Framework mit TokenAuthentication und SessionAuthentication erhalten 

CSRF fehlgeschlagen: CSRF-Token fehlt oder ist falsch

Um dies zu beheben, öffnen Sie die Apache-Konfigurationsdatei - httpd.conf. Fügen Sie folgende Zeile hinzu:

WSGIPassAuthorization On
0
Rajiv Sharma