Configure CORS with Credentials in Node.js

This article explains how to configure Cross-Origin Resource Sharing (CORS) in a Node.js application to securely allow cross-origin requests that include credentials, such as cookies, authorization headers, or TLS client certificates. You will learn how to set up the popular cors middleware in an Express application and understand the crucial configuration rules required for handling credentialed requests safely.

To enable CORS with credentials in Node.js, you must configure your server to return specific HTTP headers. When a client makes a credentialed request, the server must respond with Access-Control-Allow-Credentials: true and a specific Access-Control-Allow-Origin value that matches the requesting domain.

Step 1: Install the CORS Middleware

In an Express-based Node.js application, the easiest way to manage CORS is by using the official cors package. Install it via npm:

npm install cors

Step 2: Configure the CORS Options

When enabling credentials, you cannot use the wildcard symbol * for the origin option. The browser will block any credentialed request if the server responds with Access-Control-Allow-Origin: *. Instead, you must explicitly specify the allowed origin or origins.

Here is how to configure the middleware in your Express application:

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

const app = express();

// Define CORS options
const corsOptions = {
  origin: 'https://your-frontend-domain.com', // Replace with your frontend's URL
  credentials: true, // Allow cookies and headers to be sent
  optionsSuccessStatus: 200 // Some legacy browsers choke on 204
};

// Apply CORS middleware globally
app.use(cors(corsOptions));

app.get('/api/data', (req, res) => {
  res.json({ message: 'This response supports credentials!' });
});

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

Step 3: Handling Multiple Dynamic Origins (Optional)

If your application needs to support credentials from multiple specific domains, you can configure the origin parameter as a function. This function checks the incoming request’s origin against an allowed list:

const allowedOrigins = [
  'https://your-frontend-domain.com',
  'https://another-trusted-domain.com'
];

const corsOptions = {
  origin: function (origin, callback) {
    // Allow requests with no origin (like mobile apps or curl)
    if (!origin) return callback(null, true);
    
    if (allowedOrigins.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true
};

app.use(cors(corsOptions));

Step 4: Configure the Client Side

Configuring the Node.js backend is only half of the process; the client-side request must also explicitly request to send credentials.