NestJS enable cors in production

80,971

Solution 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

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

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

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

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,
});
Share:
80,971
Francesco Borzi
Author by

Francesco Borzi

https://github.com/FrancescoBorzi

Updated on July 09, 2022

Comments

  • Francesco Borzi
    Francesco Borzi almost 2 years

    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.

    • Beeno Tung
      Beeno Tung over 4 years
      check if you have some extension in the browser blocking 3rd javascript, e.g. NoScript and Privacy Badger
  • Georgii Rychko
    Georgii Rychko almost 6 years
    Also, I have a question: why do you build your server app using webpack? Usually, just simple tsc call is used.
  • Georgii Rychko
    Georgii Rychko almost 6 years
    Anyway if only you could share an example app where this issue gets reproduced - this way you might get help with this question much faster.
  • Francesco Borzi
    Francesco Borzi almost 6 years
    Thank you but I've already tried this solution and unfortunately it does not work. I compile for production using npm run webpack which I guess it's the default way to do it with NestJS, isn't it?
  • Georgii Rychko
    Georgii Rychko almost 6 years
    ShinDarth, have a look at this official example. There you can find how the app gets built github.com/nestjs/nest/tree/master/sample/10-fastify.
  • Georgii Rychko
    Georgii Rychko almost 6 years
    Try to build your app using this example as a basis.
  • Georgii Rychko
    Georgii Rychko almost 6 years
    Here is the compilation command from the scripts section of the package.json: "prestart:prod": "tsc". Just try to play with this example. In case you'll have questions - just put them here.
  • Karolis
    Karolis about 5 years
    app.enableCors() uses default configs which seem to be invalid for some browsers (at least Chrome complains that wildcard is not allowed). Correct way would be to use app.enableCors({ origin: /.+/ });
  • Lajos Arpad
    Lajos Arpad almost 3 years
    What's the question?