DEV Community

Cover image for Understanding Cross Origin Resource Sharing (CORS)
Peter Kelvin Torver
Peter Kelvin Torver

Posted on

Understanding Cross Origin Resource Sharing (CORS)

What is CORS?

Cross-origin resource sharing (CORS) is a mechanism that allows a client application to request restricted resources hosted on server from a different origin. These resources may include; web fonts, videos, scripts, iframes, images and stylesheets. By default, client applications making AJAX requests are only allowed to request resources that live on the same origin as the location where the client application is running.
CORS defines a way in which a browser and server can interact to determine whether it is safe to allow the cross-origin request. If an application running on different domain tries to make a XMLHttpRequest to a different domain, it will be blocked by same-origin policy.
It extends the same-origin policy and offers freedom and functionality than simply same-origin requests and it is more secured.
Poor configuration & implementation of CORS policy could lead to data access denial, data theft and potential cross-domain attacks.

Why is CORS important?

Most of the time, you client application only needs to access resources within the same origin but there are scenarios where your application needs to request resources residing on another domain and that’s where CORS comes in.
This could include your client application (React js website) makes calls to different API backend running on different domains to access resources such as images, web fonts, videos, files e.t.c
Any origin that differs from the location your client app is running on such as different scheme, domain or port needs CORS configuration in order to properly interact. This could also serve as a big security measure if your CORS is properly configured.
Different CORS request types
There are two types CORS requests which include;

  1. Simple requests with HTTP methods as GET, POST or HEAD
  2. Preflight requests with HTTP methods DELETE, PATCH, PUT e.t.c

If any of the preflight HTTP methods is used to make an XMLHttpRequest, the browser makes an automatic preflight request using the OPTIONS method. This call is used to determine if the CORS policy on the server supports the preflight request and whether or not the server can handle such request.

In this article, we are going to focus majorly on how to add CORS to a react js application and Node.js Express RESTful API.

Using CORS in react.js app and Node.js express REST API

In this article we are going to discuss the following;

  1. How to configure CORS to allow all domains to send requests to your node js server api
  2. How to configure CORS to allow a single domain to communicate with your node js server.
  3. How to configure CORS to allow multiple domains whitelisted by you to connect to your node js server.
  4. How to configure CORS with express js to allow client server communication
  5. How to proxy request in react js application to a node js server.
  6. How to fix CORS error Blocked by CORS policy

How to fix CORS error Blocked by CORS policy

If you are react js developer, you may have come across CORS error, request to a particular URI is blocked by CORS policy. This is sometimes weird at first and if you aren’t familiar with CORS, you start second guessing if your code is buggy. No, your code isn’t buggy but it is the way browsers behave by default when you’re trying to request resources to another domain.
In this article, we’re going to assume your client app is hosted on http://localhost:3000 and your server (REST API) is hosted on http://localhost:5000
Anyways, there are two ways to fix this in a react.js application which include;

Proxy configuration in package.json

Using proxy configuration within your react.js app package.json file. One thing with this solution is that it only works in development environment unless you have a way of making it to work in production.

In order to temporary fix the error, open your react js app package.json file and add the following configuration.

//other config keys
{
   “proxy”: “http://localhost:5000”
}
Enter fullscreen mode Exit fullscreen mode

If you noticed, the above configuration points to our server URL and this will allow you to make XMLHttpRequest in your client app running on the above URL.

Using CORS configuration

In order to make use of CORS, I will assume you’re making use axios library in your client-side application. Remember this is not library specific, so you can make use of native browser FETCH API.
Supposing you create an instance of axios using the code below

import axios from “axios”

export const Axios = axios.create({
    baseURL: http://localhost:5000,
    withCredentials: true
})

Enter fullscreen mode Exit fullscreen mode

The baseURL in the configuration above points to the URL of your node.js express API and the withCredentials property specifies if we want to share cookies or authentication headers with our server. The withCredentials property is totally optional and you don’t necessarily need to specify it unless you want to share cookies and auth headers.

How to add CORS in node.js express API

In order to add CORS to our API, there are different ways by which you can accomplish this. It could be by manually writing an express middleware and telling your server which requests to allow and from which origin or by using CORS npm library which has done much of the heavy lifting for us.

In this article, we will be using cors npm library which can be easily passed as an express middleware.
First of all, install calls on your server-side app by running the command

npm install cors

Enter fullscreen mode Exit fullscreen mode

Then you can add it as a middleware like this

const express = require("express");
const cors = require("cors");
const app = express();
//use cors as middleware
app.use(cors())

Enter fullscreen mode Exit fullscreen mode

The above code is the default way of adding CORS as an express middleware but what if you want to specify the origin of your client app? Well let’s learn different ways to configure CORS in node js app.

Allow requests from all domains.

To allow our node.js server to handle all requests from all domains in our application, we will have to configure cors and pass it an origin key with a wildcard value shown below.

//other imports
app.use(
  cors({
    origin: “*”,
  })
);

Enter fullscreen mode Exit fullscreen mode

The issue with the above configuration is that, you client-side application CANNOT share cookies nor authentication headers even if the credentials key is passed with a value of true as shown below.

Note: The origin key in cors option CORS take different option types such string, boolean, function or an array.

//other imports
app.use(
  cors({
    origin: “*”,
    credentials: true
  })
)
Enter fullscreen mode Exit fullscreen mode

Another key important thing to note is that, whenever you are not passing withCredentials: true in your client request API, DO NOT pass credentials: true in your cors config server-side most especially if you are using wildcard (*) as the origin of your request header.

Tell CORS to set the origin to the request origin

In order to configure CORS to set the origin to the request origin, simply pass a boolean true value to origin key as shown below;

//other imports
app.use(
  cors({
    origin: true,
    credentials: true
  })
)

Enter fullscreen mode Exit fullscreen mode

Although this will allow your client app to share cookies and auth headers with your server unlike using wildcard but this also is not well secure enough unless it’s an open API.

Configure CORS to set the origin to a single domain

In order to configure cors to set the origin to a single domain, simply pass a string true value to origin key as shown below;

//other imports
app.use(
  cors({
    origin: “http://localhost:3000”,
    credentials: true
  })
)

Enter fullscreen mode Exit fullscreen mode

The above configuration will allow your client app to accept requests only from http://localhost:3000 and share cookies and auth headers with your server. This configuration is tightly secure but not robust enough.

Configure CORS to set the origin to multiple whitelisted domains

What if you have microservice applications hosted on different domains or you want different domains to make requests to your API? Well, you can simply configure cors passing by an array of allowed domains to the origin key as shown below;

//other imports
const allowedDomains = [“http://localhost:3000”, “http://localhost:4000”, “http://localhost:6000”]
app.use(
  cors({
    origin: allowedDomains,
    credentials: true
  })
)

Enter fullscreen mode Exit fullscreen mode

The above configuration will allow your client app to accept requests from any of the above domains listed in the array and share cookies and auth headers with your server.

CORS middleware can be passed as a global middleware and on a single route but all the methods shown above are ways to globally configure your CORS within your app. Lets briefly see how we can pass CORS middleware on a single route. Note that, all the ways described above can be use on your routes as well.

const allowedDomains = [“http://localhost:3000”, “http://localhost:4000”, “http://localhost:6000”]
app.get(“/api/posts”, 
  cors({
    origin: allowedDomains,
    credentials: true
  }), 
  (req, res) =>{
    res.send(“everything still works”)
})

Enter fullscreen mode Exit fullscreen mode

NOTE: Whenever you’re a making a client-side request with the option of withCredentials: true, ensure your CORS configuration is passed credentials: true as an option as well else cookies won’t be shared. Another key important; thing to note is that, whenever you’re using wildcard () as the origin, DO NOT use *withCredentials: true** on the client and credentials: true on server

Summary:

In this article, you have learnt that CORS is a mechanism that allows requests from a particular domain to be accepted by another domain and possibly share resources with each other. You got to understand that different ways by which you can configure your CORS to allow effective communication between client apps and servers. CORS, if done properly can serve as one of the security measures ensuring that your server only accepts requests from known domains.

Video Tutorial

If you are the visual type like me, go ahead and watch the video below.
Please don't forget to like, share, comment, subscribe and turn on notification as that will give me the motivation to do more awesome videos and tutorials like this.

REFERENCES
If you want to read more about CORS, visit the following links

What is cors?
A guide to Cors

CORS

What is CORS?

Top comments (1)

Collapse
 
hamzadev profile image
Hamza Elkotb

Helpful article thank you so much