У меня есть приложение Django, работающее локально на 127.0.0.1:8000. Когда я получаю к нему доступ через 127.0.0.1:8000 в моем браузере, все в порядке. Однако, когда я получаю к нему доступ через localhost: 8000, возникают ошибки CSRF: я думаю, это происходит из-за того, что запрос AJAX POST неправильно отправляет файл cookie csrftoken
.
На той же HTML-странице у меня есть два действиякоторые отправляют POST-запросы:
один с html form
с использованием тега шаблона Django {% csrf_token %}
(который работает отлично)
другой, который использует API Fetch (AJAX) для отправки запроса POST в представление в моем приложении Django, которое отправляет обратно JSON (обратите внимание, что я не использую django-rest-framework ), и этоодин не работает.
Запрос на выборку выглядит следующим образом:
const csrftoken = getCookie('csrftoken');
fetch(route, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
credentials: 'include',
body: JSON.stringify(reqBody)
}).then(...)
Но мое представление возвращает ошибку Forbidden (CSRF cookie not set.)
, когда я выполняю этот запрос. Если я добавлю к нему декоратор @csrf_exempt
(который устраняет ошибку, но я не хочу постоянно деактивировать CSRF) и напечатаю request.META.get("CSRF_COOKIE")
, request.META.get("HTTP_X_CSRFTOKEN")
и request.META.get("HTTP_COOKIE")
, то получу следующее:
CSRF_COOKIE: None
HTTP_X_CSRFTOKEN: cdd9hIG22C39heME5aUvBU8VfB9hpnnvf8TWLYMQBJsS8jqoPh0ErA7iq1fdHSt2
HTTP_COOKIE: isNotIncognito=true; _ga=GA1.1.1965841096.1569096679; ki_t=1569096680795%3B1569096680795%3B1569096748030%3B1%3B2; ki_r=; optimizelySegments=%7B%22172074712%22%3A%22false%22%2C%22172226670%22%3A%22none%22%2C%22172411375%22%3A%22ff%22%2C%22172441755%22%3A%22direct%22%7D; optimizelyBuckets=%7B%7D; optimizelyEndUserId=oeu1569096677162r0.6862028569293451; PGADMIN_KEY=f1f0faa8-c054-48c3-a42c-a98ba6e1a4d1; PGADMIN_LANGUAGE=en
Насколько я понимаю, защита CSRF от Django проверяет CSRF_COOKIE
или HTTP_X_CSRFTOKEN
на HTTP_COOKIE
csrftoken
. Как видите, в моем HTTP_COOKIE
нет csrftoken
(хотя в моем JS я могу сделать getCookie('csrftoken')
, и это работает!). Я думаю, что это является причиной ошибки CSRF.
Любая идея, как включить csrftoken
в мой запрос HTTP_COOKIE
?
РЕДАКТИРОВАТЬ: это не дубликат этот вопрос , как вы можете видеть, я уже добавил credentials: 'include'
к своему запросу, поэтому учетные данные действительно передаются.