Understanding and Configuring CORS in Node.js and Express.js

CORS (Cross-Origin Resource Sharing) is a web security standard that enables web pages to request resources from a different domain.

Due to the Same-Origin Policy followed by web browsers for security reasons, requests for resources from a different origin than the current web page are restricted.

Therefore, CORS configuration is necessary when a web page needs to request an API from a different domain.

Installing Cors

To configure CORS in Node.js, you can use the 'cors' library. First, you need to install this library.

Setting Cors

npm install cors

Basic CORS Configuration

Configure to allow requests coming from all domains.

However, allowing requests from all domains can lead to issues. That's why detailed configurations are necessary.

These issues refer to requests for resources from different domains.

use cors

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

app.use(cors());

Intermediate CORS Configuration

To make more detailed configurations, you can pass an options object to the 'cors' function.

You can specify the desired domains in the 'origin' property. Additionally, setting the 'credentials' property to 'true' allows requests from this domain to include credentials such as cookies.

By configuring this way, when the browser sends a request to the server, the 'Access-Control-Allow-Origin' and 'Access-Control-Allow-Credentials' headers are added, ensuring compliance with CORS policies.

That concludes how to configure CORS in Node.js. By utilizing this feature, you can safely request and use resources from different domains.

basic cors setting

app.use(
  cors({
    origin: 'http://localhost:3300',
    credentials: true,
  }),
);

CORS Detailed Configuration

  1. origin: Specifies the URL of the client site. In this case, requests coming from http://localhost:3300 are allowed.
  2. methods: Specifies the allowed HTTP methods. In this case, only requests using the GET and POST methods are allowed.
  3. allowedHeaders: Specifies the request headers that the server can accept. In this case, the request headers must include Content-Type and Authorization. See Example
  4. credentials: Adds Access-Control-Allow-Credentials to the response header. In this case, requests can include cookies and authentication information. See Example
  5. maxAge: Specifies the time in seconds to cache the result of preflight requests. In this case, the result of preflight requests is cached for 600 seconds. Learn More

detail cors setting

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

app.use(
  cors({
    origin: 'http://localhost:3300',
    methods: ['GET', 'POST'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
    maxAge: 600,
  }),
);

Example of allowedHeaders

You can find the headers configuration inside the try block.

allowedHeaders

async function sendData() {
  try {
    const response = await fetch('http://localhost:3300/sample', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'token sample',
      },
      body: JSON.stringify({
        title: 'title',
        description: 'description',
      }),
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const data = await response.json()
    console.log(data)
  } catch (error) {
    console.error('Error:', error)
  }
}

sendData()

Example of Credentials

When set to credentials: 'include', the client can include cookies in the request.

On the contrary, when set to credentials: 'omit', the client does not include cookies in the request.

Just because credentials: true is set on the server, it doesn't mean credentials must always be included. Conversely, if credentials is set to false, credentials cannot be included.

credentials

fetch('http://localhost:3300/sample', {
  method: 'GET',
  credentials: 'include',
})

fetch('http://localhost:3300/sample', {
  method: 'GET',
  credentials: 'omit',
})

Example of maxAge

Using maxAge prevents unnecessary requests to the server for the same request over a specific time period.

Preflight requests are sent before the actual request, allowing the server to confirm if it can handle the request and using the HTTP OPTIONS method.

maxAge indicates the cache duration. In the example provided, setting it to 600 means the result of the request will be cached for 10 minutes. Therefore, requests cannot be sent for the same information within the next 10 minutes, reducing unnecessary preflight requests to the server.

However, even with maxAge in use, clients can ignore the cache and continue sending preflight requests.