skip to Main Content

I have deployed a Full Stack React/Node app on AWS EC2 instance using nginx and facing the CORS policy issue which I have already resolved in my code

enter image description here

Index.js

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

const app = express()
const port = process.env.PORT || 5000;

// midleware to use API Endpoints
const corsOptions = {
  origin: 'http://13.200.107.25'
}
app.use(express.json());
app.use(cors(corsOptions));


// Serving client react app build 
const path = require('path');
const _dirname = path.dirname("");
const buildPath = path.join(_dirname , "../client/build");

app.use(express.static(buildPath));

app.get('/*', (req, res) => {
  res.sendFile(
    path.join(__dirname, "../client/build/index.html"),
    (err) => {
      if(err)
      {
        res.status(500).send(err);
      }
    }
  )
})


//Available Routes
app.use('/api/auth', require('./Routes/authRoute'));
// app.use('/api/notes', require('./Routes/notes'))


app.listen(port, () => {
  console.log(`iNotebook listening at http://localhost:${port}`)
})

I used pm2 to start backend server which is also serving the ../client/build of my react app

enter image description here

I have changed /etc/nginx/sites-available/default file for configurations

server {
   listen 80 default_server;
   listen [::]:80 default_server;
    
   server_name _;
   
   location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
} 

I have restarted pm2 and nginx and test nginx syntax configurations using sudo nginx -t which is successfull

I have given corsOptions as a paramater in my index.js

// midleware to use API Endpoints
const corsOptions = {
  origin: 'http://13.200.107.25'
}
app.use(express.json());
app.use(cors(corsOptions));

2

Answers


  1. I think your cors configurations are ok.

    A good way to realize if your Headers are ok is using curl in a bash terminal.

    curl http://13.200.107.25 -I
    

    This command shows you the headers of your website:

    HTTP/1.1 200 OK
    Server: nginx/1.18.0 (Ubuntu)
    Date: Tue, 01 Aug 2023 15:56:25 GMT
    Content-Type: text/html; charset=UTF-8
    Content-Length: 1457
    Connection: keep-alive
    X-Powered-By: Express
    Access-Control-Allow-Origin: http://13.200.107.25 #<---- CORS
    Vary: Origin
    Accept-Ranges: bytes
    Cache-Control: public, max-age=0
    Last-Modified: Tue, 01 Aug 2023 14:11:19 GMT
    ETag: W/"5b1-189b1705fac"
    

    As you can see the cors header is ok.

    The problem is that your front is attempting to connect to http://localhost:5000 and this is confusing because you said that your backend (node) is in the same EC2 (not in localhost).

    If your backend is running in the same EC2 instance the solution is changing every http://localhost:5000 request in your react project for http://13.200.107.25. In this case, the CORS header is not necessary because the requests are from the same origin.

    If actually, your backend is running on your personal computer (localhost) you must configure cors(in your backend) with http://localhost… and depending on your browser configure it to allow make this request like in this question CORS error on request to localhost dev server from remote site . Because fetching localhost from websites already hosted on the internet is not secure.

    Login or Signup to reply.
  2. Assuming 13.200.107.25 is your ubuntu server the backend NojeJs + Express should be:

    const express = require('express');
    const cors = require('cors');
    require('dotenv').config();
    
    const app = express()
    const port = process.env.PORT || 5000; // ALLOWED PORT IN FIREWALL
    
    app.use((req, res, next) => {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT');
        res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');
        next(); // DONT FORGET THIS!!!
    });
    app.use(cors()); // default cors, you can change here the options
    
    
    // midleware to use API Endpoints
    app.use(express.json());
    
    
    // Serving client react app build 
    const path = require('path');
    const _dirname = path.dirname("");
    const buildPath = path.join(_dirname , "../client/build");
    
    app.use(express.static(buildPath));
    
    app.get('/*', (req, res) => {
      res.sendFile(
        path.join(__dirname, "../client/build/index.html"),
        (err) => {
          if(err)
          {
            res.status(500).send(err);
          }
        }
      )
    })
    
    
    //Available Routes
    //app.use('/api/auth', require('./Routes/authRoute')); YOURS
    // The api can be accessed like this: http://server/api
    // Like so, you can add other webservices at the same server like http://server/api1 http://server/api2 ... 
    
    app.use('/auth', require('./Routes/authRoute'));
    
    
    app.listen(port, () => {
      console.log(`iNotebook listening at http://localhost:${port}`)
    })
    

    Nginx should be:

    server {
        listen 80;
        listen [::]:80;
        # root /var/www/html; you can use for FRONT-END LATER
    
        #server_name yourdomain.com www.yourdomain.com;
        server_name 13.200.107.25;
    
        location / {
                   # First attempt to serve request as file, then
                   # as directory, then fall back to displaying a 404.
    
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_connect_timeout 2s;
            proxy_set_header 'Access-Control-Allow-Origin' *;
            proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
            proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';
    
            proxy_redirect     off;
    
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    
            add_header 'Cache-Control' 'no-cache, must-revalidate, max-age=0';
            # add response CORS headers
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
            
            expires off;
    
            gzip_static on;
    
            gzip on;
            gzip_disable "msie6";
    
            gzip_vary on;
            gzip_comp_level 6;
            gzip_proxied any;
            gzip_http_version 1.1;
    
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $http_connection;
    
            try_files $uri /index.html index.html;
        }
    
    
        location ~ .(html)$ {
                   add_header Pragma "no-cache";
                   add_header Cache-Control "no-store";
                   add_header strict-transport-security "max-age=31536000";
                   add_header X-Frame-Options "SAMEORIGIN";
                   try_files $uri /index.html;
        }
        location ~ .(css|htc|less|js|js2|js3|js4)$ {
                   expires 31536000s;
                   add_header Pragma "public";
                   add_header Cache-Control "max-age=31536000, public";
                   try_files $uri /index.html;
        }
    
        location /api/ {
            rewrite ^/api/?(.*)$ /$1 break;    
            proxy_pass  http://127.0.0.1:5000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
        error_page  405     =200 $uri;
    }
    
    

    http://13.200.107.25/api will access your backend API.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search