![]() |
VOOZH | about |
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.
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).
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.
While developing locally, you might not have strict domain separation, but in production, enabling CORS is vital for several reasons:
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.
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-expressYou 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:
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.
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.
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://www.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();
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.
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.
In production environments, you may want different CORS settings than in development. You can handle this by using environment variables.
1. Add Environment Variables: In your .env file, add:
CORS_ORIGINS=https://www.frontend.com/,https:/another-frontend.com2. 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.
When enabling CORS in production, it’s important to follow security best practices to ensure your application is protected:
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: