Nest.js is giving cors error even when cors is enabled
Asked Answered
P

8

13

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.

Photocopy answered 6/1, 2022 at 15:39 Comment(8)
See developer.mozilla.org/en-US/docs/Web/HTTP/…Prepositor
@Prepositor I also tried writing it like origin: http://localhost:3000. It still didn't work.Photocopy
You're using the wildcard (*), not just for the origin, but also for the headers. As explained in the MDN Web Docs I linked to above, that won't work in conjunction with credentialed requests. Instead, try allowedHeaders: ['content-type'].Prepositor
What is the actual error message? There are different types of CORS errors.Unreflecting
@Unreflecting see the screenshots.Photocopy
I don't see a error message there. Just the screenshot of the network tab which says "CORS error". Have a look in the console output, there will be a more detailed error messageUnreflecting
@Unreflecting my cors errors are gone. But now I am getting a 404 not found error even though auth/login exists in my auth controllerPhotocopy
maybe in the frontend you putted 'localhost ' insead of 'http : // localhost'Karinkarina
P
14

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,
});
Prepositor answered 6/1, 2022 at 16:0 Comment(2)
Cors error solved. But now I am getting a 404 not found error which is even weirder considering it worked a few days agoPhotocopy
@Photocopy I don't expect the 404 to be related to your earlier CORS issue. You should probably ask a separate question about it, if cannot find a solution by yourself.Prepositor
L
2

Found this better expressive and work nice


const whitelist = [
      'http://localhost:3000',
      'http://localhost:3001',
      'http://localhost:3002',
      'http://localhost:8000',
      'http://127.0.0.1:3000',
      'http://127.0.0.1:3001',
      'http://127.0.0.1:3002',
      'http://10.0.2.2:3000',
    ];

const app = await NestFactory.create(AppModule, {
    logger,
    cors: {
      methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'],
      origin: function (origin, callback) {
        if (!origin) {
          callback(null, true);
          return;
        }
        if (
          whitelist.includes(origin) || // Checks your whitelist
          !!origin.match(/yourdomain\.com$/) // Overall check for your domain
        ) {
          console.log('allowed cors for:', origin);
          callback(null, true);
        } else {
          console.log('blocked cors for:', origin);
          callback(new ImATeapotException('Not allowed by CORS'), false);
        }
      },
    },
  });

Logrolling answered 20/8, 2023 at 11:0 Comment(0)
G
0

In my case I needed pass content-type: application/x-www-form-urlencoded in Request Header using axios.

Giuditta answered 28/12, 2022 at 19:6 Comment(0)
A
0

I've fixed it for my case.

const app = await NestFactory.create(AppModule, {
    bodyParser: true,
  });


  app.enableCors({
    "origin": "*",
    "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
    "preflightContinue": false,
    "optionsSuccessStatus": 204
  });
Aspersion answered 2/4, 2023 at 18:14 Comment(0)
E
0

I have got the same issue and tried every thing with cors, But the actual issue was graphQL default disable playground on production mode. enter image description here

add these to apollo config

  `const server = new ApolloServer({
    introspection: true,
    playground: true,
  });`
Elman answered 14/6 at 13:36 Comment(0)
D
0

HTTPS, PRODUCTION, SSL, NGINX

Nginx Configuration

    server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/sites-available/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/sites-available/ssl/private.key;
    ...

Note: I created the ssl directory myself for storing SSL certificate (certificate.crt) and private key (private.key) files, so do not look for it in /etc/nginx/sites-available/. You can create your own directory for storing secret files, or configure it according to your setup. Make sure to update all paths in both the Nginx configuration and the NestJS main file (main.ts or bootstrap.ts) to reflect your setup.

NEST JS

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

async function bootstrap() {
  const httpsOptions = {
    cert: fs.readFileSync('/etc/nginx/sites-available/ssl/certificate.crt'),
    key: fs.readFileSync('/etc/nginx/sites-available/ssl/private.key'),
  };

  const app = await NestFactory.create(AppModule, {
    httpsOptions,
  });

  // Enable CORS for specific origin and credentials
  app.enableCors({
    origin: 'https://frontend.com',
    credentials: true,
  });

  await app.listen(3000);

}

bootstrap();

References HTTPS nest JS docs

Displace answered 16/6 at 23:32 Comment(0)
A
-1

In my case I followed the official docs which says following to enable CORS on nestjs

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

but I still got the CORS error because of a CORS plugin which I installed long time ago.

So I switched off "Allow CORS" plugin in my browser and the error is gone. (If you have any similar plugin turn it off and see if it's working for you.)

Acetous answered 1/5, 2022 at 7:44 Comment(2)
if you not finding this answer helpful mention why here OR mention your issue with my answer here so that i can improve my answer!Acetous
you are suggesting only to do the basic cors and the questions say they already do that, and switched off "Allow CORS" don't solve the problem, other person that use the app and don't have that in the browser will have the problem of the corsTalky
C
-1

This solution in my case that similar, I enable cors in the nest.js to fetch data in my react application.

In your nest application do this:

first step: install: https://www.npmjs.com/package/cors-ts

npm i cors-ts

second step:

import cors from 'cors-ts'

and paste this:

app.use(
  cors({
    origin: '#front-end-url',
    optionsSuccessStatus: 200,
  })
)

into your file main.ts and then restart your applications.

Celebrity answered 13/3, 2023 at 10:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.