Search code examples
node.jstypescriptgraphqlcorsapollo

cors problem with node, typescript, apollo and graphql


I'm getting corns with my application. Have I configured my server incorrectly ? I'm trying to create a user in my PostgreeSQL database via the frontend. I've made a tsx component which is a form. When I submit the data, it returns a cors error, my frontend being at localhost:3000 and my backend at localhost:4000. Despite all the configuration I've done, it doesn't work. However, my preflight request works, returning a code 204, but not my fetch request, which returns a cors error.

Here's my code:

import express from "express";
import cors from "cors";
import { ApolloServer } from "apollo-server-express";
import schema from "../graphql/schema";

const app = express();
const port = process.env.PORT || 4000;

const whitelist = ["http://localhost:3000"];

const corsOptions: cors.CorsOptions = {
  origin: (origin: any, callback: any) => {
    if (whitelist.indexOf(origin) !== -1 || !origin) {
      callback(null, true);
    } else {
      callback(new Error("Not allowed by CORS"));
    }
  },
  methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
  credentials: true,
  optionsSuccessStatus: 204,
};

app.use(cors());

app.get("/", (req, res) => {
  res.send("Hello, World!");
});

const server = new ApolloServer({
  schema,
  context: ({ req, res }) => ({
    req,
    res,
  }),
  plugins: [
    {
      async requestDidStart({ request, context }) {
        return {
          async willSendResponse({ response }) {
            response.http?.headers.set("Apollo-Require-Preflight", "true");
          },
        };
      },
    },
  ],
});

const startServer = async () => {
  await server.start();
  server.applyMiddleware({
    app,
    path: "/graphql",
    cors: false,
  });
  app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
  });
};

startServer();

my network : enter image description here

and here, the error :

localhost/:1 Access to fetch at 'http://localhost:4000/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

This is my first frontend application with a backend and this problem has been blocking me for days. The strange thing is that one request has already been successful, but the second time it wasn't. I don't know what else to try. Thanks in advance for your help, coding friends!


Solution

  • const allowedOrigins = ['https://example.com', 'https://another-domain.com'];
    
    app.use(cors({
      origin: (origin, callback) => {
        if (allowedOrigins.includes(origin) || !origin) {
          callback(null, true);
        } else {
          callback(new Error('Not allowed by CORS'));
        }
      }
    }));
    

    I hope this assists, I would just opt for helmet and adjust CORS how you like.