Reputation:
The problem that I am facing is that I cannot fetch an existing user from my NextJS frontend. The backend framework that I use is Django (along with the django-cors-headers package). django-cors-headers does not allow a certain HTTP request, while it should.
My next.config.js contains a rewrite, so that I can access my backend.
async redirects() {
return [
{
source: '/api/:path*',
destination: 'http://localhost:8000/:path*/',
permanent: true,
},
]
},
And my django-cors-headers settings look like this:
# CORS
CSRF_TRUSTED_ORIGINS = [
'http://localhost:3000',
]
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000',
'http://localhost:8000',
'http://127.0.0.1:3000',
'http://127.0.0.1:8000',
]
CORS_ALLOW_ALL_ORIGINS = True
The request that fails attempts to fetch a user with an ID of 1. This user exists and therefore, this request should succeed.
fetch(`/api/users/${String(userId)}/`, {
mode: 'cors',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
})
However, the only thing that I get back from the request is an error message about CORS.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/users/1.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Status code: 301.
It looks like my django-cors-headers setup is wrong. But I am allowed to obtain my JWT tokens. The following request succeeds.
fetch('/api/token', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: mail,
password,
}),
})
Upvotes: 3
Views: 14579
Reputation: 31
I have the same problem. I tried to call Django API in react app and this error bugged me for a few days, but I found the solution.
Upvotes: 3
Reputation:
I tried pretty much everything EXCEPT for double checking the load order of my middleware... I fixed my issue by going from the following load order
MIDDLEWARE = [
# Default
'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',
# CORS
'corsheaders.middleware.CorsMiddleware',
]
... to
MIDDLEWARE = [
# CORS
'corsheaders.middleware.CorsMiddleware',
# Default
'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',
]
I knew that it had to be something simple, but now I just feel like a grand idiot...
Upvotes: 8
Reputation: 3378
With CORS, we have a couple of things that need to be considered. You could find more in here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers, go to Access-Control links.
Your config above, you've set up:
So if your app using credentials, then change CORS_ALLOW_CREDENTIALS to True. If it's still not working, check your request headers, make sure that there are no special headers in there and if you do have special headers on your request, it's better be inside of CORS_ALLOW_HEADERS.
Upvotes: 2
Reputation: 49291
This is the settings for django cors headers. in settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# add this
'corsheaders',
]
MIDDLEWARE = [
# add this
'corsheaders.middleware.CorsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'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',
]
# set this
CORS_ALLOW_ALL_ORIGINS=True
Status code: 301
indicates that requested resource is invalid, so the request should be redirected to a proper url. Most likely you are sending request to an invalid endpoint
Upvotes: 0