CSRF Ошибка: токен CSRF отсутствует или неверен
Я использую Django 1.7 и django-rest-framework.
Я создал API, который возвращает мне некоторые данные JSON, помещающие это в мой settings.py
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
в настройку...
Я понятия не имею, что происходит. Кто-нибудь знает, в чем проблема?
Ответы
Ответ 1
Когда вы используете SessionAuthentication, вы используете аутентификацию Django, которая обычно требует проверки CSRF. Django REST Framework обеспечивает это, только для SessionAuthentication
, поэтому вы должны передать токен CSRF в заголовок X-CSRFToken
.
Документация Django содержит дополнительную информацию о извлечении токена CSRF с помощью jQuery и отправке его в запросы. Маркер CSRF сохраняется как файл cookie с именем csrftoken
, который вы можете получить из ответа HTTP, который зависит от используемого языка.
Если вы не можете получить cookie CSRF, это обычно признак того, что вы не должны использовать SessionAuthentication
. Я рекомендую изучить TokenAuthentication или OAuth 2.0 в зависимости от ваших потребностей.
Ответ 2
Это то, что я сделал, чтобы решить эту проблему, я включил токен 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")
}
});
Ответ 3
У меня была похожая проблема, я обернул свои URL в методе csrf_exempt
как -
from django.views.decorators.csrf import csrf_exempt
url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())),
Ответ 4
1- Поиск заголовка Cookie
![enter image description here]()
2- Отделить csrftoken от sessionid
3- Добавьте X-CSRFToken = {.. csrftoken, который вы извлекли на шаге 2..} см. Ниже
4- Опубликовать снова
Ответ 5
У нас была эта проблема, и оказалось, что это ошибка Почтальона. Они были автоматически посылать csrftoken
и sessionid
значения по умолчанию, которые мы не проходящие в заголовке. Следующие инструкции помогли решить проблему: https://avilpage.com/2019/02/django-tips-csrf-token-postman-curl.html.
Ответ 6
У меня была похожая проблема, когда я обернул представления с помощью csrf_exempt
и все еще сталкивался с ошибками. Оказалось, что я неправильно получал URL, поэтому он был преобразован в "не найденный" обратный вызов (который не был освобожден от CSRF) и, следовательно, выдавал исключение, прежде чем я мог сказать, что URL неправильный.
Ответ 7
// 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);
}
}
});
Ответ 8
Получить токен из 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-запроса:
this.$http.post(server,{params: {foo: 'bar'}}, {headers: {"X-CSRFToken":csrftoken }}).then(function (response) {
this.response = response.data;
},
function (response) {
console.log(response);
});
Ответ 9
Когда вы размещаете сайт django на сервере Apache. Djando rest framework с TokenAuthentication и SessionAuthentication получит
Ошибка CSRF: токен CSRF отсутствует или неверен
Чтобы исправить это, откройте конфигурационный файл Apache - httpd.conf Добавьте следующую строку:
WSGIPassAuthorization On
Ответ 10
Это единственное решение, которое сработало для меня, я сталкивался.
https://khalsalabs.com/disable-csrf-verification-for-django/