Ich versuche Parameter wie zu posten
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
Forbidden 403. CSRF verification failed. Request aborted.
Ich verwende jedoch Django return 'django.middleware.csrf.CsrfViewMiddleware'
und konnte nicht herausfinden, wie ich dieses Problem verhindern kann, ohne die Sicherheit zu beeinträchtigen.
django
jquery
django-csrf
brsbilgic
quelle
quelle
Antworten:
Sie können AJAX-Post-Anfragen auf zwei verschiedene Arten stellen:
Um Ihrer Ansicht mitzuteilen, dass das csrf-Token nicht überprüft werden soll. Dies kann mit einem Dekorateur
@csrf_exempt
wie folgt erfolgen:from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_view_name(request): ...
Um ein csrf-Token in jede AJAX-Anforderung einzubetten, kann es für jQuery sein:
$(function () { $.ajaxSetup({ headers: { "X-CSRFToken": getCookie("csrftoken") } }); });
Wo die
getCookie
Funktion csrf-Token von Cookies abruft. Ich benutze die folgende Implementierung:function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf(c_name + "="); if (c_start != -1) { c_start = c_start + c_name.length + 1; c_end = document.cookie.indexOf(";", c_start); if (c_end == -1) c_end = document.cookie.length; return unescape(document.cookie.substring(c_start,c_end)); } } return ""; }
Außerdem hat jQuery ein Plugin für den Zugriff auf Cookies.
// set cookie $.cookie('cookiename', 'cookievalue'); // read cookie var myCookie = $.cookie('cookiename'); // delete cookie $.cookie('cookiename', null);
quelle
X-CSRFToken
und nichtX-CSRF-Token
das ist, was auch häufig verwendet wirdcsrf_exempt
Decorator kann zu Sicherheitsproblemen führen, da der Middleware-Schutz deaktiviert wird.{{ csrf_token }}
die erste Option nicht rendern kann, wurde mein Problem gelöst.Der einfachste Weg, den ich gefunden habe, besteht darin, den
{{csrf_token}}
Wert in die Daten aufzunehmen:jQuery.ajax( { 'type': 'POST', 'url': url, 'contentType': 'application/json', 'data': { 'content': 'xxx', 'csrfmiddlewaretoken': '{{ csrf_token }}', }, 'dataType': 'json', 'success': rateReviewResult } );
quelle
window.csrftoken="{{csrftoken}}";
{{ csrf_token }}
das Formular hinzu und erhalte den Wert voncsrf_token = $('input[name="csrfmiddlewaretoken"]').val();
unddata = {'para1': 'para1_value', csrfmiddlewaretoken: csrf_token};
Ich habe eine Weile gebraucht, um zu verstehen, was ich mit dem Code machen soll , den Daniel gepostet hat. Aber eigentlich müssen Sie es nur am Anfang der Javascript-Datei einfügen.
Für mich ist die bisher beste Lösung:
Ein ... kreieren
csrf.js
DateiFügen Sie den Code in das Feld ein
csrf.js
Datei einVerweisen Sie auf den Code in der Vorlage, die Sie benötigen
<script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
Beachten Sie, dass
STATIC_PREFIX/js/csrf.js
auf meine Datei verweist. Ich lade tatsächlich dieSTATIC_PREFIX
Variable mit{% get_static_prefix as STATIC_PREFIX %}
.Erweiterter Tipp: Wenn Sie Vorlagen verwenden und etwas haben, von
base.html
dem aus Sie sich erweitern, können Sie von dort aus einfach auf das Skript verweisen, und Sie müssen sich in den restlichen Dateien keine Sorgen mehr machen. Soweit ich weiß, sollte dies auch kein Sicherheitsproblem darstellen.quelle
the code
meinen Sie genau jedes einzelne Zeichen im grünen Hintergrund? Ich kopiere, füge das ein und tue, was du gesagt hast, erhalte aber immer noch einen verbotenen Fehler. Vielleicht haben sich die Dinge geändert?src="{{ STATIC_PREFIX }}js/csrft.js"
. Beachten Sie, dass STATIC_PREFIX eine Variable ist. Ich setze diese Variable mit{% get_static_prefix as STATIC_PREFIX %}
. Stellen Sie jedoch sicher, dass dassrc
auf die richtige Stelle zeigt.Einfach und kurz
$.ajaxSetup({ headers: { "X-CSRFToken": '{{csrf_token}}' } });
ODER
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", '{{csrf_token}}'); } } });
docs
quelle
Mangels einer einfachen Antwort müssen Sie nur den Header
X-CSRFToken
zur Ajax-Anfrage hinzufügen, die im Cookie enthalten istcsrftoken
. JQuery macht keine Cookies (aus irgendeinem Grund) ohne Plugin, also:<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
und die minimale Codeänderung ist:
$.ajax({ headers: { "X-CSRFToken": $.cookie("csrftoken") }, ... });
quelle
Ich habe gestern das gleiche Problem bekommen und dachte, es würde den Leuten helfen, wenn es eine einfache Möglichkeit gäbe, damit umzugehen. Deshalb habe ich ein jQuery-Plugin dafür geschrieben: jquery.djangocsrf . . Anstatt das CSRF-Token in jeder Anforderung hinzuzufügen, hängt es sich an das AjaxSend jQuery-Ereignis an und fügt das Client-Cookie in einen Header ein.
So verwenden Sie es:
1- schließen Sie es ein:
<script src="path/to/jquery.js"></script> <script src="path/to/jquery.cookie.js"></script> <script src="path/to/jquery.djangocsrf.js"></script>
2- Aktivieren Sie es in Ihrem Code:
$.djangocsrf( "enable" );
Django fügt das Token immer in ein Cookie ein, wenn Ihre Vorlage verwendet wird
{% csrf_token %}
. Verwenden Sie den@ensure_csrf_cookie
Dekorator , um sicherzustellen, dass es immer hinzugefügt wird, auch wenn Sie das spezielle Tag in Ihrer Vorlage nicht verwenden :from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def my_view(request): return render(request, 'mytemplate.html')
Hinweis: Ich verwende Django 1.6.2.
quelle
Vielen Dank an alle für alle Antworten. Ich benutze Django 1.5.1. Ich bin etwas spät zur Party, aber jetzt geht es los.
Ich habe den Link zum Django-Projekt gefunden sehr nützlich, wollte aber nicht jedes Mal, wenn ich einen Ajax-Aufruf tätigen wollte, den zusätzlichen JavaScript-Code einfügen müssen.
Ich mag Jerrykans Antwort, da sie sehr prägnant ist und einem ansonsten normalen Ajax-Anruf nur eine Zeile hinzufügt. Wie wäre es mit dem Laden des csrfmiddlewaretoken aus dem DOM als Antwort auf die Kommentare unter seinem Kommentar zu Situationen, in denen keine Django-Vorlagen-Tags verfügbar sind?
var token = $('input[name="csrfmiddlewaretoken"]').prop('value'); jQuery.ajax({ type: 'POST', url: url, data: { 'csrfmiddlewaretoken': token }, dataType: 'json', success: function(data) { console.log('Yippee! ' + data); } });
EDIT März 2016
Mein Ansatz zu diesem Thema hat sich in den letzten Jahren geändert. Ich füge den folgenden Code (aus den Django-Dokumenten ) zu einer main.js-Datei hinzu und lade ihn auf jeder Seite. Sobald Sie fertig sind, sollten Sie sich keine Gedanken mehr über das CSRF-Token mit Ajax machen müssen.
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]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken');
quelle
Include -
x-csrftoken
Header in Anfrage:var token = $('input[name="csrfmiddlewaretoken"]').prop('value'); jQuery.ajax({ type: 'POST', url: url, beforeSend : function(jqXHR, settings) { jqXHR.setRequestHeader("x-csrftoken", get_the_csrf_token_from_cookie()); }, data: data, dataType: 'json', });
quelle
Die schnellste Lösung ohne Plugins, wenn Sie js nicht in Ihre Vorlage einbetten, ist:
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
Fügen Sie vor Ihren Verweis auf die Datei script.js in Ihre Vorlage ein und fügen Sie siecsrfmiddlewaretoken
Ihremdata
Wörterbuch hinzu:$.ajax({ type: 'POST', url: somepathname + "do_it/", data: {csrfmiddlewaretoken: window.CSRF_TOKEN}, success: function() { console.log("Success!"); } })
Wenn Sie Ihre js in die Vorlage einbetten, ist dies so einfach wie:
data: {csrfmiddlewaretoken: '{{ csrf_token }}'}
quelle
Wenn nach dem Lesen anderer Antworten immer noch Probleme auftreten, versuchen Sie Folgendes:
$.ajax({ type: "POST", beforeSend: function (request) { request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}"); }, url: servlet_path, data : data, success : function(result) { console.log("Success!"); } });
quelle
beforeSend
ob die Eigenschaft den Token nicht richtig greift ...?Bitte beachten Sie nicht, dass Sie auf diese Weise sicherstellen müssen, dass
{% csrf_token %}
die<form></form>
Tags nicht enthalten sind . Fügen Sie dann, wie hier erläutert , den folgenden Code zu Ihrem Javascript hinzufunction getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); // using js fetch // https://docs.djangoproject.com/en/3.1/ref/csrf/#setting-the-token-on-the-ajax-request const request = new Request( /* URL */, {headers: {'X-CSRFToken': csrftoken}} ); fetch(request, { method: 'POST', mode: 'same-origin' // Do not send CSRF token to another domain. }).then(function(response) { // ... });
quelle