I have been trying for a while to send a POST or DELETE request from my Vue front-end to my Django backend.
I am running Vue.js on my localhost:3000, and Django on localhost:8000. I have set up CORS with django-cors-headers, and I am able to GET requests. However, once I try to DELETE or POST, I get this error:
Forbidden (CSRF cookie not set.)
I understand, that I need to pass a CSRF token in my request's header, which I have:
deleteImage() {
const url = this.serverURL + 'images/delete/' + this.image_data.pk;
const options = {
method: "DELETE",
headers: {'X-CSRFToken': this.CSRFtoken}
};
fetch(url, options)
.then(response => {
console.log(response);
if (response.ok){
// if response is successful, do something
}
})
.catch(error => console.error(error));
}
I obtain this.CSRFtoken
from a GET request, and the token is the same if I use the approach shown in Django docs.
My Django settings.py
looks like this:
rom pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '***'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'serveImages.apps.ServeimagesConfig',
'django_admin_listfilter_dropdown',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000"
]
CSRF_TRUSTED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000"
]
And I know by default django-cors-headers allows the header X-CSRFToken
.
I have gone through all previous questions on StackOverflow about this topic, and nothing seems to work.
More context:
views.py
from django.http import JsonResponse
import os
from django.conf import settings
from django.middleware import csrf
from .models import Image
def get_csrf_token(request):
token = csrf.get_token(request)
return token
# return JsonResponse({'CSRFtoken': token})
def index(request, dataset, class_label):
payload = {}
images_folder_url = os.path.join('static', 'images', dataset, class_label.lower())
payload['base_url'] = images_folder_url
data_query = Image.objects.filter(dataset__name=dataset, label__name=class_label).values('pk', 'path', 'isIncluded')
payload['image_data'] = list(data_query)
payload['number_of_images'] = len(payload['image_data'])
payload['CSRFtoken'] = get_csrf_token(request)
return JsonResponse(payload)
def delete_image(request, img_pk):
print(request)
# Just for testing
return JsonResponse({'status': '200'})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('get-token', views.get_csrf_token, name='CSRFtoken'),
path('images/<str:dataset>/<str:class_label>', views.index, name='index'),
path('images/delete/<int:img_pk>', views.delete_image, name='delete_image'),
]