Enabling CORS with NestJS and GraphQL on localhost
Published 2020-05-26
Photo by Shane Rounce on Unsplash
I recently had a somewhat frustrating experience with enabling CORS in a NestJS app that uses GraphQL Apollo server and cookie authentication. The client and server apps are both running on localhost but on two different ports. A few StackOverflow questions and Github issues exist but none had answers that worked for me.
The Red Herring 🐟
Many resources online will say to enable CORS and put configuration on app
, like so:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({ // wrong! in my case, anyway
origin: 'http://localhost:3000',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
allowedHeaders: 'Content-Type, Accept',
credentials: true,
});
await app.listen(3001);
console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();
But be careful!! This may work for building a REST API, but not for GraphQL!
Even though origin
is set to the correct url, Chrome will still show this as repsonse headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
But Firefox appears to show the missing piece. The browser appears to send an OPTIONS
preflight request to /graphql
that does have the correct origin set, but the subsequent POST /graphql
does not have origin set.
OPTIONS /graphql
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Accept
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: http://localhost:3000
POST /graphql
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
The Solution 🎉
Since I'm using GraphQL, what worked was to actually put the CORS configuration in the GraphQLModule#forRoot()
options.
@Module({
imports: [
GraphQLModule.forRoot({
cors: {
origin: 'http://localhost:3000',
credentials: true,
},
}),
The first OPTIONS
request to /graphql
looks the same, but the subsequent POST
has the correct headers now:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Production settings may require this to change but for now this is working on a localhost setup.
Happy coding 👩💻
#nestjs#graphql#http