Ich versuche Parameter zu posten
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
Django gibt jedoch Forbidden 403. CSRF verification failed. Request aborted.
.__ zurück. Ich verwende 'Django.middleware.csrf.CsrfViewMiddleware'
und konnte nicht finden, wie ich dieses Problem verhindern kann, ohne die Sicherheit zu beeinträchtigen.
Sie können AJAX auf zwei verschiedene Arten einen Post-Request stellen:
Um Ihrer Ansicht mitzuteilen, das CSRF-Token nicht zu überprüfen. Dies kann mit dem Dekorator @csrf_exempt
wie folgt durchgeführt werden:
from Django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def your_view_name(request):
...
Um ein CSRF-Token in jede Anforderung von AJAX einzubetten, kann es für jQuery Folgendes sein:
$(function () {
$.ajaxSetup({
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
});
Wo die getCookie
-Funktion das csrf-Token von Cookies abruft. Ich verwende 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');<br>
// read cookie
var myCookie = $.cookie('cookiename');<br>
// delete cookie
$.cookie('cookiename', null);
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
}
);
Ich habe eine Weile gebraucht, um zu verstehen, was ich mit dem Code tun sollte, das Daniel gepostet hat. Aber eigentlich müssen Sie es nur am Anfang der Javascript-Datei einfügen.
Für mich ist die beste Lösung bisher:
Erstellen Sie eine csrf.js
-Datei
Fügen Sie den Code in die csrf.js
-Datei ein
Verweisen 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 die Variable STATIC_PREFIX
tatsächlich mit {% get_static_prefix as STATIC_PREFIX %}
.
Erweiterter Tipp: Wenn Sie Vorlagen verwenden und etwas wie base.html
haben, von dem aus Sie erweitern, können Sie das Skript von dort aus referenzieren und Sie müssen sich keine Sorgen mehr um den Rest Ihrer Dateien machen. Soweit ich weiß, sollte dies auch keine Sicherheitslücke darstellen.
Einfach und kurz
$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' }
});
OR
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}}');
}
}
});
Ich habe gestern das gleiche Problem bekommen und dachte, es würde den Leuten helfen, wenn es einen einfachen Weg geben würde, also schrieb ich ein jQuery-Plugin dafür: jquery.djangocsrf . Anstatt das CSRF-Token in jeder Anforderung hinzuzufügen, bindet es sich selbst an das AjaxSend-Ereignis jQuery und fügt das Client-Cookie in einem Header hinzu.
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 {% csrf_token %}
verwendet. Um sicherzustellen, dass es immer hinzugefügt wird, auch wenn Sie das spezielle Tag in Ihrer Vorlage nicht verwenden, verwenden Sie den Dekorator @ensure_csrf_cookie
:
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.
Vielen Dank an alle für alle Antworten. Ich benutze Django 1.5.1. Ich bin ein bisschen spät auf der Party, aber hier geht es.
Ich fand den Link zum Django-Projekt sehr nützlich, aber ich wollte nicht unbedingt den zusätzlichen JavaScript-Code einbinden, wenn ich einen Ajax-Aufruf machen wollte.
Ich mag jerrykans Antwort, da sie sehr knapp ist und nur eine Zeile zu einem ansonsten normalen Ajax-Anruf hinzufügt. Als Antwort auf die Kommentare unter seinem Kommentar zu Situationen, in denen Django-Vorlagen-Tags nicht verfügbar sind, wie wäre es mit dem Laden der csrfmiddlewaretoken aus dem DOM?
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
Meine Einstellung zu diesem Thema hat sich in den letzten Jahren geändert. Ich füge den folgenden Code (von Django docs ) zu einer main.js-Datei hinzu und lade ihn auf jeder Seite. Wenn Sie fertig sind, müssen Sie sich nicht mehr um den CSRF-Token mit ajax kümmern.
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');
x-csrftoken
-Header in die Anfrage einschließen:
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',
});
Da es keine direkte Antwort gibt, müssen Sie lediglich den Header X-CSRFToken
zur ajax-Anforderung hinzufügen, die sich im Cookie csrftoken
befindet. JQuery verwendet keine Cookies (aus irgendeinem Grund) ohne ein Plugin so:
<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") },
...
});
Die schnellste Lösung ohne Plugins, wenn Sie keine js in Ihre Vorlage einbetten, ist:
Fügen Sie <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
vor Ihrem Verweis auf die Datei script.js in Ihre Vorlage ein und fügen Sie dann csrfmiddlewaretoken
in Ihr data
-Wörterbuch ein:
$.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 es so einfach: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}
Wenn jemand nach dem Lesen anderer Antworten immer noch Probleme hat, 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!");
}
});