I've gone through a lot of other threads and discussion forums, but none solved exactly. This solution refers to few settings in the settings.py I've applied them, Django CSRF Cookie Not Set
I'm posting this question because I've tried other solutions but none exactly fixed it.
This is also a just the beginning of a server, I made the project, started an app, & created a view for POST request. Let me know if any other code is required...
My views.py nothing, just a basic return. When I add @csrf_exempt
it works but I can't really do that.
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
views.py
from django.http import HttpResponse
import json
# Create your views here.
def Product(request):
if request.method == "POST":
try:
data = json.loads(request.body) # Parse JSON data from the request body
if "data" in data:
response_data = str(data["data"]) # Get the value of 'data' key
return HttpResponse(response_data, content_type="text/plain")
else:
return HttpResponse(
"Invalid JSON data. 'data' key is missing.", status=400
)
except json.JSONDecodeError:
return HttpResponse("Invalid JSON data.", status=400)
else:
return HttpResponse("This API only accepts POST requests.")
Settings.py
"""
Django settings for app_server project.
Generated by 'django-admin startproject' using Django 4.2.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import environ
from pathlib import Path
env = environ.Env()
environ.Env.read_env()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
SESSION_COOKIE_SECURE = None
SESSION_COOKIE_HTTPONLY = True
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
# Add other trusted origins here if needed
]
CSRF_COOKIE_DOMAIN = [
"http://localhost:3000",
# Add other cookie domain here if needed
]
CSRF_TRUSTED_ORIGINS = [
"http://localhost:3000",
# Add other CSRF trusted origins here if needed
]
ALLOWED_HOSTS = [
"*"
# "localhost",
# Add other allowed hosts here if needed
]
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"corsheaders",
"rest_framework",
"products",
]
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly",
]
}
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "app_server.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "app_server.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
I'm making a request from React frontend as:
function getCSRFToken() {
const csrfCookie = document.cookie.match(/(^|;)csrftoken=([^;]+)/);
return csrfCookie ? csrfCookie[2] : "";
}
const handleSubmit = (e) => {
const csrfToken = getCSRFToken();
fetch("http://127.0.0.1:8000/products/", {
method: "POST",
body: JSON.stringify({
data: 1,
info: "No",
}),
headers: {
"Content-Type": "application/json",
"X-CSRFToken": csrfToken,
},
}).then((response) => console.log(response));
};
I've tried printing the csrfToken and it's valid. Thanks in advance.