[Fixed] CORS Errors with Cloudflare, ExpressJS and ReactJS on nginx

Issue

I am stuck on being unable to overcome CORSĀ errors after switching to domain name via Cloudflare. I just can’t seem to get the backend api to use the domain name like https://www.my_domain.com/api

What I have done:

  1. Applied nginx solution and restarted nginx
  2. In cloudflare I updated DNS management with three A records: *, www, and <my_domain.com>
  3. In cloudflare Always Use HTTPS is set to On
  4. ExpressJS enabled cors library
  • Applied nginx solution below…
    Note: I have React running on port 3000. React shows when visiting the domain name in the browser!
location /api {
    proxy_pass http://localhost:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}


location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}
  • Command I used to test and restart nginx:

sudo nginx -t && sudo systemctl restart nginx

  • In cloudflare DNS management…
A record, Name: *, Content: <server_ip>, TTL: Auto, Proxy status: DNS only
A record, Name: <my_domain_name>, Content: <server_ip>, TTL: Auto, Proxy status: Proxied
A record, Name: www, Content: <server_ip>, TTL: Auto, Proxy status: Proxied
  • In cloudflare, SSL/TLS,Edge Certificates, Always Use HTTPS is set to On.

  • ExpressJS enabled cors library

And certainly, I have added the cors library to express like so:

const express = require("express");
const cors = require("cors");
require('dotenv').config()

const app = express();

if (process.env.NODE_ENV === 'production') {
    app.use(cors({ origin: `${process.env.CLIENT_URL}` }));
}
  • my backend .env file:
NODE_ENV=production
CLIENT_URL=http://my_domain.com
  • my frontend react .env file
CLIENT_URL=/api

I noticed also that in the browser console, it shows the request is being sent as http://<server_ip>:8000/api and not https:<domain_name>/api as is expected.

Also, I just made the change to the domain name today.

Despite having these settings above, when I try to login, I see the request gets blocked due to cors error.

What could be causing the cors error?

Solution

Followed this tutorial…

https://medium.com/@nishankjaintdk/serving-a-website-on-a-registered-domain-with-https-using-nginx-and-lets-encrypt-8d482e01a682

Resulted in discovering these instructions…

https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx

Ran these commands (from the certbot instructions) in my linux terminal…

sudo snap install core; sudo snap refresh core; sudo apt-get remove certbot; sudo snap install --classic certbot; sudo ln -s /snap/bin/certbot /usr/bin/certbot; sudo certbot --nginx

There was a prompt for domain names at this point. So, I entered my domains like this…

my_domain.com www.my_domain.com

Per the instructions, I then tested the renewal (you’ll need to annually renew but these will be put into cron for *hopefully autorenew)

sudo certbot renew --dry-run

The domain api worked but the react app did not show yet, indicating perhaps some issue in Cloudflare.

After, I got my website to show up in the browser like this…

  1. Logged into Cloudflare.com
  2. Went to the domain’s SSL/TLS encryption settings
  3. Changed it from Flexible to Full
  4. Clicked on the Edge certificates
  5. Turned off the HTTPS Always On

After doing all of the above, it resulted in the domain showing my react app which fully worked with the api and no CORS errors.

Leave a Reply

(*) Required, Your email will not be published