Express CORS – Configure CORS headers

In this article, I have covered different Express CORS examples. Cross-Origin Resource Sharing (CORS) is a security feature in web browsers that restricts web applications from making requests to a different domain than the one that served the application. However, there are cases where cross-origin requests are necessary. Using the npm package cors with Express.js, developers can enable CORS in their applications, allowing for these essential requests to be performed under controlled conditions.

Express CORS Examples

Table of Contents

Installation of Express CORS package

Installing the cors package is a straightforward process. Begin by opening your terminal and navigating to your project directory. Then, run the following npm command:

npm install cors

Basic Usage of CORS in Express

To use the cors package in an Express application, include the following lines in your server code:

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());

app.get('/resource', (req, res) => {
  res.json({ msg: 'This is CORS-enabled for all origins!' });


app.listen(3000, () => {
  console.log('Server listening on port 3000');
});

Simple Usage

app.use(cors());

The default configuration of cors() allows all origins (*), all methods, and includes some default headers. This is useful during development but might not be suitable for production, where you might want to restrict access to specific origins, methods, and headers for security reasons.

 

Allow Specific Origin

In this example, the origin option is set to 'https://example.com', meaning that only requests coming from this specific origin are allowed. If a request originates from a different domain, it will be blocked by the browser.

const corsOptions = { origin: 'https://example.com' };
app.use(cors(corsOptions));

Allow Multiple Origins

The allowedOrigins array specifies a list of permitted origins, and the middleware allows cross-origin requests only if the incoming request’s origin matches one in the predefined list. This fine-grained approach enhances security by selectively permitting access to specific domains while rejecting requests from unauthorized origins.

const allowedOrigins = ['https://example.com', 'https://anotherdomain.com'];
app.use(cors({
  origin: function (origin, callback) {
    if (allowedOrigins.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  }
}));

allowedOrigins contains a list of origins that are allowed to make cross-origin requests to your server. In the provided example, requests from https://example.com and https://anotherdomain.com are allowed.

 

Allow All Origins

Allowing any origin to access a particular route:

app.get('/public-resource', cors(), (req, res) => {
  res.json({ msg: 'This is open to the world!' });
});

With this configuration, any web page, from any origin, can make a GET request to the /public-resource

 

Allow Credentials

Allowing cookies or authorization headers in a CORS request:

const credentialsCors = { credentials: true, origin: 'https://example.com' };
app.use(cors(credentialsCors));
  1. credentials: true: This property indicates that the server allows requests to include credentials (such as cookies, HTTP authentication, or client certificates). When set to true, the server responds to cross-origin requests with the appropriate CORS headers to indicate that credentials are allowed.
  2. origin: 'https://example.com': This property specifies the allowed origin(s) that are permitted to make cross-origin requests to the server. In this case, requests originating from https://example.com are allowed.

So, the credentialsCors object is configuring CORS to allow cross-origin requests with credentials from the specified origin. This is particularly useful when you have authentication or session-related information that needs to be sent with the cross-origin request. The server will include the necessary headers to allow the browser to send and receive such credentials securely.

Configuring CORS with specific HTTP methods:

Below code is for configuring the Express.js application to allow cross-origin requests only from https://example.com and permitting specific HTTP methods .

app.use(cors({
  origin: 'https://example.com',
  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE'
}));
  1. origin: 'https://example.com': This restricts cross-origin requests to be allowed only from the specified origin (https://example.com). Requests from other origins will be denied.
  2. methods: 'GET,HEAD,PUT,PATCH,POST,DELETE': This specifies the HTTP methods that are allowed for cross-origin requests. In this case, GET, HEAD, PUT, PATCH, POST, and DELETE are all allowed.

Enabling CORS based on a dynamic condition:

const dynamicCors = {
  origin: function (origin, callback) {
    const isWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, isWhitelisted);
  },
  credentials: true
};
app.use(cors(dynamicCors));

Configuring CORS preflight Options

Configuring CORS for preflight requests involves handling HTTP OPTIONS requests that browsers send before making certain cross-origin requests. These preflight requests check whether the actual request (e.g., a POST request with custom headers) is safe to send. In Express.js, you can use the app.options method with the cors() middleware to handle preflight requests for specific routes, ensuring that the necessary CORS headers are set for these initial requests. This allows the browser to determine whether the subsequent cross-origin request is allowed, contributing to a secure and well-configured Cross-Origin Resource Sharing setup.

app.options('/complex-cors', cors()); 
//enabling pre-flight request for DELETE request

app.delete('/complex-cors', cors(), (req, res) => {
  res.json({ msg: 'CORS-enabled for all origins!' });
});

Conclusion

In this article, we have explored various ways to configure the ‘express cors’ middleware to manage cross-origin requests in an Express.js application. From basic setups to dynamic origin validations, the examples provided should assist developers in implementing CORS as per their specific needs. It is essential to properly handle CORS to ensure application security while allowing necessary resources to be accessible across different domains.

 

References