Search code examples
pythondjangonode.jscorsdjango-cors-headers

How to avoid Cross-Origin Resource Sharing error when hitting a Django API from another server process?


I am building a WebApp that has two separate components:

  1. A "frontend" node.js application server (running on localhost:3099) that web-visitors will visit
  2. A "backend" Django server (running on localhost:3098) that manages my ORM and talks to the database. Web visitors will not interact with this server directly at all. This server simply publishes a RESTful API that will be consumed by the frontend.

I will implement security restrictions that will prevent anyone except the frontend server from accessing the backend's API.

One of the API endpoint the backend publishes looks like this: http://localhost:3098/api/myApi/.

I can successfully hit that API from curl like so: curl -X POST -H "Content-Type: application/json" -d '{"myKey1":"myVal1", "myKey2":"myVal2"}' http://localhost:3098/api/myApi/

However, when I try to hit that same API from my frontend server using Javascript, I get the following error in my browser's console window:

XMLHttpRequest cannot load http://localhost:3098/api/myApi/. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3099' is therefore not allowed access. 

To solve this, took the following steps:

  1. I installed django-cors-headers
  2. I added 'corsheaders' to my INSTALLED_APPS
  3. I added 'corsheaders.middleware.CorsMiddleware' to MIDDLEWARE_CLASSES above 'django.middleware.common.CommonMiddleware'
  4. I declared the whitelist: CORS_ORIGIN_WHITELIST = ('localhost', '127.0.0.1',)

However, implementing django-cors-headers seems to have made no difference. I'm still getting the same CORS error. How can I solve this issue?


Solution

  • CORS is port-sensetive. Specification says that

    If there is no port component of the URI:
    1.  Let uri-port be the default port for the protocol given by uri-scheme.
    Otherwise:
    2.  Let uri-port be the port component of the URI.
    

    And

    If the two origins are scheme/host/port triples, the two origins are the same if, and only if, they have identical schemes, hosts, and ports.

    This means that, with your spec CORS handles your whitelist as localhost:80, 127.0.0.1:80. I believe specifying localhost:3099 should resolve this issue.