title: CORS issue with Django and React hosted on same server
body: <p>I am having a CORS issue with my Django Rest Framework and React app on the same server. I am running Vagrant with an Ubuntu 18 box and NGINX installed (I am assuming this issue will translate to DigitalOcean) I apologize ahead of time if I am providing too much information. DRF is using Supervisor and Gunicorn is on port 8000. I created my React app using create-react-app. I then used <code>npm run build</code> to create the static files.</p>
  
  <p><strong>NGINX Setup:</strong></p>
  
  <p>React Conf</p>
  
  <pre><code>server {
      listen 8080;
      server_name sandbox.dev;
  
      root /var/sites/sandbox/frontend/build;
      index index.html;
      client_max_body_size 4G;
      location / {
          try_files $uri $uri/ /index.html;
      }
  </code></pre>
  
  <p>Django Conf</p>
  
  <pre><code>upstream sandbox_server {
      server unix:/var/tmp/gunicorn_sanbox.sock fail_timeout=0;
  }
  server {
      listen 8000;
      server_name api.sandbox.dev;
      ...
      location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      if (!-f $request_filename) {
          proxy_pass http://sandbox_server;
          break;
      }
  </code></pre>
  
  <p><strong>Django Setup:</strong></p>
  
  <pre><code>INSTALLED_APPS = [
      ...
      'rest_framework',
      'corsheaders',
      'myapp',
  ]
  MIDDLEWARE = [
      'corsheaders.middleware.CorsMiddleware',
      ...
  ]
  </code></pre>
  
  <p>I have tried the following with no luck</p>
  
  <pre><code>CORS_ORIGIN_ALLOW_ALL = True
  </code></pre>
  
  <p>and</p>
  
  <pre><code>CORS_ORIGIN_ALLOW_ALL = False
  CORS_ORIGIN_WHITELIST = ('192.168.19.76:8080','localhost:8080',)
  </code></pre>
  
  <p><strong>React App.js</strong></p>
  
  <pre><code>...
  fetch("http://localhost:8000/api/v1/token-auth/", {
      method: 'POST',
      headers: {
         'Content-Type': 'application/json',
      },
      body: JSON.stringify({"email":"test@user.com", "password":"testuser"}),
  })
  </code></pre>
  
  <p>So to state the obvious CORS is correct because the Origin is localhost:8080 which is a different port so it sees it as cross origin. I have tried the different settings with cors origin allow, but it is still the same issue every time. Obviously I am doing something wrong, but I can't see it. </p>
  
  <p>My thoughts are</p>
  
  <p>Option 1</p>
  
  <p>proxy pass using the django nginx conf file and do away with the react nginx conf file, but I don't know what affect that might cause in production or if this is a good idea. Is there a better way?</p>
  
  <pre><code>location /api {
      proxy_set_header X-Forwarded_for $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://sandbox_server;
  </code></pre>
  
  <p>So finalize my thoughts and my question. After trying the different Django options for CORS I am still getting the CORS error. Why, and is it my NGINX conf files causing it or something else? Will I expect to see this in DigitalOcean?</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>I forgot to add the error. Here is the CORS error</p>
  
  <pre><code>Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/api/v1/token-auth/. (Reason: CORS request did not succeed).
  </code></pre>
  
  <p>For those wanting to know the output from the network tab</p>
  
  <pre><code>Host    localhost:8000
  Origin  http://192.168.19.76:8080
  Pragma  no-cache
  Referer http://192.168.19.76:8080/
  </code></pre>
  
  <p><strong>UPDATE 2</strong>
  I did test using curl, and everything returned as expected so I know DRF is working corrently.</p>
  
  <pre><code>curl --data "email=test@user.com&amp;password=testuser" http://localhost:8000/api/v1/token-auth/
  </code></pre>
  
  <p><strong>FINAL UPDATE</strong></p>
  
  <p>Thanks to paulsm4 for all the help and just plain awesomeness.</p>
  
  <p>So, I did abandon django-cors-headers and rolled my own. To answer paulsm4's question, I do not have <code>add_header 'Access-Control-Allow-Origin' '*';</code> in the NGINX file although I did think about letting NGINX handle CORS vs Django, but never went that far. @paulsm4, this is the proxy_pass I was talking about. The key was adding this block of code to NGINX for the react portion in conjunction with my middleware.</p>
  
  <pre><code>    location /api {
          proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://sandbox_server;
  </code></pre>
  
  <p>The above code by itself worked, but it did not allow me to whitelist any incoming URLs. Creating my own middleware allowed me to whitelist. I have no idea why django-cors-headers or even django-cors-middleware did not work for me. What was strange was that fetch never made it far enough with those two packages to get response headers and an error of any sorts, other than the CORS error I was asking about. With the middleware I wrote, fetch was able to fully make the call, and return some response headers whether it succeeded or failed.</p>
  
  <p>For future reference, I might revisit NGINX and allowing it to handle CORS. Here is a good link
  <a href="https://enable-cors.org/server_nginx.html" rel="noreferrer">CORS on NGINX</a></p>
  
  <p><strong>NOTE</strong></p>
  
  <p>To clarify; the only middleware installed besides what Django already includes is the cors middleware. Both Django and React reside on the same server, but with different ports.</p>
  
  <ol>
  <li>api.sandbox.com:8000 is the Django Rest Framework</li>
  <li>app.sandbox.com:8080 is the React static files </li>
  <li>Django 2.0.2 </li>
  <li>Python 3.6 </li>
  <li>django-cors-headers 2.4.0 </li>
  <li>Vagrant/VirtualBox Ubuntu 18.04 </li>
  <li>NGINX</li>
  </ol>
  
  <p>Django settings.py</p>
  
  <pre><code>INSTALLED_APPS = [
      ...
      # Third Party
      'rest_framework',
      'corsheaders',
      # My Apps
      'account',
  ]
  
  MIDDLEWARE = [
      'corsheaders.middleware.CorsMiddleware',
      'django.middleware.common.CommonMiddleware',
      ...
      'django.middleware.csrf.CsrfViewMiddleware',
      'corsheaders.middleware.CorsPostCsrfMiddleware',
      ...
  ]
  CORS_ORIGIN_WHITELIST = (
      'null',
      '192.168.19.76:8080',
      'localhost:8080',
      'app.sandbox.com:8080'
  )
  </code></pre>
  
  <p>React App.js</p>
  
  <pre><code>    fetch("http://localhost:8000/api/v1/token-auth/", {
          method: 'POST',
          headers: {
              'Content-Type': 'application/json',
          },
          body: JSON.stringify({
              "email": "test@user.com", 
              "password": "testuser"
         }),
      })
  </code></pre>
  
  <p>So I am at wits end here. It is either django-cors-headers that is not working or it could possibly be NGINX. </p>