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,
}),
})
CodePudding user response:
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
CodePudding user response:
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:
- CORS_ALLOWED_ORIGINS: http://localhost:8000, ...
- CORS_ALLOW_METHODS: "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT" (default)
- CORS_ALLOW_CREDENTIALS: False (default)
- CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", ] (default)
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.