I have a question about cors implementation in django.
Having a problem with setting the correct cors values.
My deployment is on docker.
I have a deployed 3 containers:
- backend: Django + DRF as backend (expose 8000 port)
- Nginx to server my backend (use exposed 8000 port and set it to 1338)
- frontend React app used with nginx (uses port 1337)
Everything is on localhost.
I use axios from frontend to call get/post requests. (I call to 1338 port then I think it is redirected to internal service on 8000 port)
For backend I had to install django-cors-headers package to work with CORS.
I think I set up it correctly. But there are scenarios where it does not work.
In settings.py
INSTALLED_APPS = [
...
"corsheaders",
]
...
MIDDLEWARE = [
...
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...
]
Nginx.conf for nginx image:
upstream backend {
server backend:8000;
}
server {
listen 80;
add_header Access-Control-Allow-Origin *;
location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:1337;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/staticfiles/;
}
}
First scenario
In settings.py
CORS_ALLOW_ALL_ORIGINS = True
No get/post requests work. Get message:
CORS Multiple Origin Not Allowed
Second scenario
In settings.py
CORS_ALLOWED_ORIGINS = ["http://localhost:1337"]
Works with get requests, but does not work with post requests.
For post requests:
- options with error: CORS Missing Allow Header
- post with error: NS_ERROR_DOM_BAD_URI
It works if I am not using nginx for backend.
Adding request headers as requested in the comment.
I am not sure what else could I add here. So my deployed project is here (it also is easy to launch if you have docker on your machine:
https://gitlab.com/k.impolevicius/app-001
2
Answers
Good day, seems that problem is in
axios.post
not in Django or nginx.Because if you do curl post or post from drf browsable api, it works fine:
But react app generates this
OPTIONS
request:I have come across this issue a while back, and I think the issue is with the headers.
In the MDN docs, it is stated here that other than for the simple requests, we’ll get preflighted requests with OPTIONS method. There are 3 main headers that we need to send in response in your case
From the looks of it you have configured the first header and you should be seeing it in the network tab too, and since the error is about missing allow headers, you need to add
Access-Control-Allow-Methods
headerto your nginx file
Seeing your network tab on the requested headers will give more context here, generally you should be seeing
Access-Control-Request-Method
andAccess-Control-Request-Headers
headers in theOPTIONS
request. If there are some headers that you aren’t allowing, please write an nginx rule for the same. You can look into this solution for more reference