'NestJS enable cors in production

I've enabled CORS in my NestJS app following the official tutorial, so my main.ts looks like the following:

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter(), { cors: true });
  await app.listen(3000);
}
bootstrap();

and it works when I run the application using npm run start:dev.

However when I try to first compile the application using npm run webpack and then running it using node server.js, the cors will not work.

The http request from the client will fail with:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 404.



Solution 1:[1]

Somehow the issue was compiling it using npm run webpack. If I compile it using prestart:prod then it will work.

Thanks @georgii-rychko for suggesting it via comments.

Solution 2:[2]

Try to use an approach described in here https://docs.nestjs.com/techniques/security#cors

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);

Solution 3:[3]

If you are running NestJs with graphql you will run into a problem where Apollo server will override the CORS setting see link. This below fixed the problem. I wasted 8 hrs of my life on this. :-( I hope you see this and you don't do that. see link and link

        GraphQLModule.forRoot({
            debug: process.env.NODE_ENV !== 'production',
            playground: process.env.NODE_ENV !== 'production',
            typePaths: ['./**/*.graphql'],
            installSubscriptionHandlers: true,
            context: ({req}) => {
                return {req};
            },
            cors: {
                credentials: true,
                origin: true,
            },
        }),

then in your main.ts:

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

Solution 4:[4]

I was able to get it working by giving my own origin function. The complete enableCors function would be like for NestJS or any NodeJS server like:

var whitelist = ['https://website.com', 'https://www.website.com'];
app.enableCors({
origin: function (origin, callback) {
  if (whitelist.indexOf(origin) !== -1) {
    console.log("allowed cors for:", origin)
    callback(null, true)
  } else {
    console.log("blocked cors for:", origin)
    callback(new Error('Not allowed by CORS'))
  }
},
allowedHeaders: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe',
methods: "GET,PUT,POST,DELETE,UPDATE,OPTIONS",
credentials: true,
});

and the appOptions if you are using NestJS Express:

const app = await NestFactory.create<NestExpressApplication>(AppModule);

Solution 5:[5]

Sad to know that you also tried:

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);

And it's still not working.


Ensure that on your server side you have cors enabled, which should be something like this:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
  next();
});

And also ensure that your browser is cors supported. If all these still doesn't work, I will advice you download Allow-Control-Allow-Origin extension for Chrome, it should fix your issue.

Solution 6:[6]

maybe you get undefined in origin with the following whitelist .If you do not want to block REST tools or server-to-server requests, add a !origin check in the origin function like so:

const whitelist = ['example.com', 'api.example.com'];
app.enableCors({
  origin: function (origin, callback) {
    if (!origin || whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  },
  ...
});

Solution 7:[7]

Bellow is my main.ts that finally worked pretty well.

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
    const app = await NestFactory.create<NestExpressApplication>(
        AppModule,
    );

    app.useStaticAssets(join(__dirname, '..', 'public'));
    app.setBaseViewsDir(join(__dirname, '..', 'views'));
    app.setViewEngine('hbs');

    app.use((req, res, next) => {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
        next();
    });

    app.enableCors({
        allowedHeaders:"*",
        origin: "*"
    });

    await app.listen(3000);
}

bootstrap();

Solution 8:[8]

The documentation for the cors config object is here: https://github.com/expressjs/cors#configuration-options

I noticed nobody used an array for the origin, so in case anyone wanted some quick copy pasta

And in case you were wondering, I researched it too... http and https is considered different and so are subdomains or lack thereof (www.example.com and app.example.com).

app.enableCors({
  origin: [
    'http://localhost:3000',
    'http://example.com',
    'http://www.example.com',
    'http://app.example.com',
    'https://example.com',
    'https://www.example.com',
    'https://app.example.com',
  ],
  methods: ["GET", "POST"],
  credentials: true,
});

Solution 9:[9]

None of the answers had worked until I realized nest start would run with no issues when I deleted my main.ts file.

Check that your main.ts is actually being called.

If it's not, deleting the /dist folder should do the trick.

Solution 10:[10]

async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.enableCors()
await app.listen(3000); 
}
bootstrap();

Solution 11:[11]

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

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

  app.enableCors({credentials: true, origin: "http://localhost:3000"});

  await app.listen(PORT, () => console.log(`Server started`));
}

bootstrap();

Instead of "http://localhost:3000" paste your url client

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Francesco Borzi
Solution 2 SharkofMirkwood
Solution 3
Solution 4 cyperpunk
Solution 5 antzshrek
Solution 6
Solution 7 Dharman
Solution 8 wongz
Solution 9
Solution 10 Shuvro
Solution 11 Leonar