How to fix Access-Control-Allow-Origin error for graphql express apollo server

40 Views Asked by At

I am trying to connect my front end to my back end on my production environment, but the front end site is getting this error when testing and on the front end page:

Access to fetch at 'https://[url to page]/graphql' from origin '[route to hosted front end]' 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'.

here is the tech stack: backend - node.js express apollo server

frontend - nextjs (pages router) nx monorepo react

here is the main.ts file


async function addGraphQLMiddleware(
  app: Express,
  redisClient: Redis,
  context: Omit<AppContext, 'request' | 'response' | 'redis'>
): Promise<void> {
  const httpServer = createHttpServer(app);
  const graphQlServer = new ApolloServer({
    plugins: [
      ApolloServerPluginDrainHttpServer({ httpServer })
    ],
    schema: await buildSchema({
      resolvers,
      validate: true
    })
  });

  await graphQlServer.start();

  app.use(
    '/graphql',
    expressMiddleware(graphQlServer, {
      context: async ({ req, res }): Promise<AppContext> => {
        return {
          redis: redisClient,
          request: req,
          response: res,
          ...context
        };
      }
    })
  );
}
...redis config stuff
async function main(): Promise<void> {
  const app = express();

  app.use(cors({
    credentials: true,
    origin: environment.urls.web
  }));


  console.log('Environment', environment);
  console.log('Environment URL', environment.urls.web);

  app.use(bodyParser.json());

  app.use('/assets', express.static(pathJoin(__dirname, 'assets')));

  app.get('/api', (_req, res) => {
    res.send({ message: 'Welcome to ai-api' });
  });

  await Promise.all([
    addGraphQLMiddleware(app, redisClient, {
      dataLoaders: {
        emailLoader: createEmailDataLoader(),
        userLoader: createUserDataLoader()
      }
    }),
    addRedisSessionMiddleware(app, redisClient),
    initializeDataSource()
  ]);

  const port = process.env.PORT || 3333;
  const server = app.listen(port, () => {
    console.log(`Listening at http://localhost:${port}/api`);
  });

  server.on('error', console.error);
}

main();

and here is the next config file:

//@ts-check

// eslint-disable-next-line @typescript-eslint/no-var-requires
const { composePlugins, withNx } = require('@nx/next');

/**
 * @type {import('@nx/next/plugins/with-nx').WithNxOptions}
 **/
const nextConfig = {
  nx: {
    svgr: false
  },
  experimental: {},
  // next.config.js
  async headers() {
    return [
      {
        // Adjust this pattern to match your GraphQL API route
        source: '/:path*',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'false' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE,OPTIONS' },
          { key: 'Access-Control-Allow-Headers', value: 'Content-Type,Authorization' }
        ]
      }
    ];
  }
};

const plugins = [
  withNx
  // Add more plugins here if necessary
];

module.exports = composePlugins(...plugins)(nextConfig);

I have tried setting credentials to false, origin to '*' I can connect to the graphql with postman I can connect to the '/api' endpoint on the frontend - Just not the graphql

0

There are 0 best solutions below