Django выдает ошибку 403 (CSRF Cookie не установлен), несмотря на передачу токена в заголовке запроса из приложения React/Vite
Ситуация такова: у меня есть форма в react frontend, которая пытается отправить некоторые данные в Django backend. Когда Django view освобожден от CSRF, вся функциональность в порядке. Однако, когда я удаляю декоратор освобождения, Django всегда выбрасывает ошибку 403 - CSRF cookie not set.
Я убедился, что в заголовке запроса действительно передается токен, но по какой-то причине ошибка 403 все равно вылетает. Я нашел похожую тему с аналогичной проблемой (Django и React: csrf cookie is not being set in request header), однако из того, что я видел, я уже использовал предложенные исправления.
Во-первых, у меня есть маршрут, настроенный для первоначальной передачи CSRF-токена на фронтенд, следующим образом:
@ensure_csrf_cookie
def get_csrf_token(request):
csrf_token = get_token(request)
return JsonResponse({'csrfToken': csrf_token})
Вместе со следующим JS для запроса токена:
const getCSRFToken = async () => {
const apiUrl = import.meta.env.VITE_API_URL;
const response = await fetch(`${apiUrl}getCSRFToken/`, {
method: "GET",
credentials: "include",
});
const data = await response.json();
return data.csrfToken;
};
useEffect(() => {
// Fetch CSRF token on component mount
getCSRFToken().then((csrfToken) => {
Cookies.set("csrftoken", csrfToken); // Store the token in a cookie
});
}, []);
Запрос get ВСЕГДА работает. И с помощью editthiscookie я убедился, что cookie также сохраняются.
Дополнительно вот функция submit для формы:
const handleSubmit = async (e) => {
e.preventDefault();
// Prepare form data to send to Django
const formDataToSend = new FormData();
formDataToSend.append("fullName", formData.fullName);
// etc
// API URL for the Django backend
const apiUrl = import.meta.env.VITE_API_URL;
const csrfToken = Cookies.get("csrftoken"); // Get the CSRF token from the cookie
await fetch(`${apiUrl}contributeRequest/requestform/`, {
method: "POST",
headers: {
"X-CSRFToken": csrfToken, // CSRF token from the cookie
},
body: formDataToSend,
credentials: "include",
})
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
console.log("SUCCESS:", data);
setSubmitMessage("Your form has been successfully submitted!");
.catch((error) => {
console.error("FAILED:", error);
setSubmitMessage("There was an error submitting your form. Please try again.");
});
};
Когда я проверяю заголовки запроса при отправке формы, X-CSRFToken
устанавливается в качестве значения cookie.
и ниже приведены мои соответствующие настройки django:
CORS_ALLOWED_ORIGINS = [ env('FRONTEND_URL'), ]
CSRF_TRUSTED_ORIGINS = [ env('FRONTEND_URL'), ]
CORS_ALLOW_CREDENTIALS = True
CSRF_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_HTTPONLY = False
// I have tried the following false and true, both yield the same result
CSRF_COOKIE_SECURE = True
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# ... other middleware ...
]
Если бы я мог получить некоторые рекомендации о том, как я могу решить эту проблему, это было бы замечательно.