Search code examples
typescriptcorsnestjs

Nest.js is giving cors error even when cors is enabled


I am developing a next.js application with nest.js as the backend. Now, I am having cors error even when I have cors enabled in my main.ts file of nest.js.

Here's my main.ts file.


    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import cookieParser from 'cookie-parser';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      if (process.env.APP_ENV !== 'production') {
        app.enableCors({
          allowedHeaders: '*',
          origin: '*',
          credentials: true,
        });
      } else {
        app.enableCors({
          origin: process.env.FE_URL,
          credentials: true,
        });
      }
    
      app.use(cookieParser());
      await app.listen(process.env.PORT || 5000);
    }
    bootstrap();

I also tried the following.


    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import cookieParser from 'cookie-parser';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      
      app.enableCors({
        allowedHeaders: '*',
        origin: '*',
        credentials: true,
      });
    
      app.use(cookieParser());
      await app.listen(process.env.PORT || 5000);
    }
    bootstrap();

I also tried this


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

Now, from the frontend in _app.js, I am defining Axios global config like the following.


    axios.defaults.baseURL = 'http://localhost:5000';
    axios.defaults.withCredentials = true;

Then in my login.tsx file, I am sending the request to the nest.js application like the following.


    const {data } = await axios.post('/auth/login', values);

Here's values is an object that has a username and password.

Here is the error.

Cors Error

Cors Error Description

I also tried every other solution from other StackOverflow questions. But none of them solved my problem. It actually worked a few days ago. I don't know what happened.

What am I doing wrong here? It's been driving me bananas now. If you need, I can provide more code.


Solution

  • As explained on the MDN Web Docs about CORS, you cannot use the wildcard (*), whether it be to allow an origin or request headers (or request methods), in conjunction with credentialed requests. A more authoritative (though perhaps more dry) resource is the Fetch standard:

    For Access-Control-Expose-Headers, Access-Control-Allow-Methods, and Access-Control-Allow-Headers response headers, the value * counts as a wildcard for requests without credentials. For such requests there is no way to solely match a header name or method that is *.

    Accordingly, the following code produces a dysfunctional CORS middleware; you could argue that your CORS middleware library should prevent its users from producing such a dysfunctional CORS middleware, but it sadly does not.

    app.enableCors({
      allowedHeaders: '*',
      origin: '*',
      credentials: true,
    });
    

    Instead, you should eschew the wildcard altogether and explicitly specify the allowed origin and allowed request headers, like so:

    app.enableCors({
      allowedHeaders: ['content-type'],
      origin: 'http://localhost:3000',
      credentials: true,
    });