We have sometimes gone with the django package django-cors-headers
while developing but that does not feel right in production. We would rather handle the CORS headers directly in Nginx.
Below is a snippet that You can use in Your project to offload CORS request handling to Nginx.
Javascriptif ($request_method = 'GET') {
# 1. Allow any origin
add_header 'Access-Control-Allow-Origin' '*' always;
# 2. Credentials can be cookies, authorization headers or TLS client certificates
add_header 'Access-Control-Allow-Credentials' 'true';
# 3. What methods should be allowed when accessing the resource in response to a preflight request
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
# 4. Access-Control-Allow-Headers response header is used in response to a preflight request to indicate which HTTP headers can be used during the actual request.
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
Read more on Access-Control-Allow-Origin
Read more on Access-Control-Allow-Credentials
Read more on Access-Control-Allow-Methods
Read more on Access-Control-Allow-Headers
A more complete configuration can be found below. You will have to customize the snippet below to meet Your needs when it comes HTTPS and so on.
server {
listen 80;
server_name www.example.com;
#
# Your configuration here...
#
location / {
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
add_header Cache-Control private;
add_header Cache-Control no-cache;
add_header Cache-Control no-store;
add_header Cache-Control must-revalidate;
add_header Pragma no-cache;
uwsgi_pass unix:///tmp/uwsgi.sock;
include /etc/nginx/uwsgi_params;
proxy_read_timeout 1800;
uwsgi_read_timeout 1800;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
return 204;
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'PATCH') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}
Happy coding!