Open In App

NestJS Enable Cors In Production

Last Updated : 30 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Cross-Origin Resource Sharing (CORS) is a security feature implemented by browsers to restrict web pages from making requests to domains other than the one from which they were originally served. While CORS is critical for preventing unauthorized data access, it often needs to be configured properly to allow legitimate requests from different domains, especially in production environments.

When building RESTful APIs with NestJS, enabling CORS (Cross-Origin Resource Sharing) is essential, especially when your front-end and back-end are hosted on different domains. In this article, we'll cover how to enable CORS in production for a NestJS application, including why CORS is necessary, and different configuration options.

What is CORS?

CORS is a browser mechanism that enables controlled access to resources located outside of a given domain. It allows websites to make requests to a different origin (domain, protocol, or port) while ensuring security. Without CORS, your browser would block these requests to prevent cross-origin issues, which are typically indicative of malicious activity such as Cross-Site Request Forgery (CSRF).

Example Use Case

  • Frontend on Domain A: https://frontend.com
  • Backend on Domain B: https://api.backend.com

If frontend.com needs to fetch data from api.backend.com, the browser enforces CORS rules to either allow or block the request based on the server's response headers.

Why Enable CORS in Production?

While developing locally, you might not have strict domain separation, but in production, enabling CORS is vital for several reasons:

  • Security: CORS prevents unauthorized requests from different domains, mitigating potential attacks like CSRF.
  • Cross-Domain Communication: If your API is consumed by different front-end applications (e.g., web, mobile, third-party apps), you need to specify which domains are allowed to access your resources.
  • Scalability: In modern applications, it's common to host services on different subdomains or microservices that interact with each other. CORS is required to allow these services to communicate securely.

Setting Up CORS in NestJS

NestJS provides a simple and flexible way to enable CORS both in development and production environments. You can either enable CORS globally or configure it for specific routes or controllers.

Step 1: Installing Dependencies

NestJS comes with built-in support for CORS, so you don't need any external dependencies. However, ensure you have the latest version of NestJS installed:

npm install @nestjs/core @nestjs/common @nestjs/platform-express

Step 2: Enabling CORS Globally in NestJS

You can enable CORS globally in NestJS within the main application file (main.ts). This is the simplest approach to allow cross-origin requests across the entire application.

Here’s how you can do it:

Basic CORS Setup

In your main.ts file, enable CORS when initializing the app:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Enable CORS
app.enableCors();

await app.listen(3000);
}
bootstrap();

The app.enableCors() method activates CORS with default settings, which allows requests from any origin.

Step 3: Configuring CORS with Options

While enabling CORS globally with default settings might work for development, in production environments, it’s crucial to configure CORS more securely by specifying allowed origins, methods, and headers.

Example: Enabling CORS with Specific Options

You can pass an options object to enableCors() to control how CORS behaves. Here's an example:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Enable CORS with custom options
app.enableCors({
origin: ['https://frontend.com', 'https://another-frontend.com'], // Allowed origins
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // Allowed methods
credentials: true, // Allow credentials (e.g., cookies)
allowedHeaders: 'Content-Type, Accept', // Allowed headers
});

await app.listen(3000);
}
bootstrap();

Step 4: Enabling CORS for Specific Routes

If you don’t want to enable CORS globally, you can enable it only for specific routes, controllers, or modules. This can be useful if you have more fine-grained control over which resources are exposed.

Example: Enabling CORS for a Specific Controller

import { Controller, Get } from "@nestjs/common";

@Controller("users")
export class UsersController {
@Get()
@Cors({ origin: "https://specific-frontend.com" }) // Enable CORS for this route
findAll() {
return ["user1", "user2"];
}
}

Here, CORS is enabled only for the GET /users route, and only requests from https://specific-frontend.com will be allowed.

Step 5: Environment-Specific CORS Settings

In production environments, you may want different CORS settings than in development. You can handle this by using environment variables.

Example: Using Environment Variables for CORS

1. Add Environment Variables: In your .env file, add:

CORS_ORIGINS=https://frontend.com,https://another-frontend.com

2. Load Environment Variables: In your main.ts, load and apply the environment-specific CORS configuration:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';

dotenv.config(); // Load .env file

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Enable CORS with environment variables
const allowedOrigins = process.env.CORS_ORIGINS?.split(',') || [];

app.enableCors({
origin: allowedOrigins,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
});

await app.listen(3000);
}
bootstrap();

This approach allows you to set different origins for different environments by modifying the .env file without changing your code.

Step 6: CORS Security Best Practices

When enabling CORS in production, it’s important to follow security best practices to ensure your application is protected:

  • Whitelist Origins: Always specify allowed origins instead of using '*'. Only allow trusted domains to access your API.
  • Limit Allowed Methods: Restrict HTTP methods to those that are necessary (e.g., GET, POST) to minimize exposure to potential attacks.
  • Credentials: If your API uses authentication via cookies, set credentials: true and ensure that only specific origins can send credentials.
  • Headers: Specify the headers that the client is allowed to send. Restrict this to only the required headers to reduce attack surfaces.

Step 7: Testing CORS in Production

Once you’ve configured CORS, it’s important to test it in your production environment. Here’s how you can verify that your CORS setup is working:

  • Browser Dev Tools: Use the Network tab in browser developer tools to inspect the request headers and check for the Access-Control-Allow-Origin response header.
  • Postman or cURL: Send requests to your API from different origins to ensure CORS is enforced properly.
  • Third-Party Tools: Use online tools like Test CORS to simulate requests and verify your CORS setup.

Next Article

Similar Reads