Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why are my cors headers being ignored? #77

Open
iambumblehead opened this issue Jan 10, 2023 · 3 comments
Open

Why are my cors headers being ignored? #77

iambumblehead opened this issue Jan 10, 2023 · 3 comments

Comments

@iambumblehead
Copy link

When doing an introspection query, the koa integrated service seems to ignore the cors headers being set by the aplication. Cors headers are set this way,

ctx.status = 200;
ctx.set('access-control-allow-credentials', 'true');
ctx.set('access-control-allow-origin', host);
ctx.set('access-control-allow-headers', corsHeadersAccepted);
ctx.set('access-control-allow-methods', 'OPTIONS');
ctx.set('access-control-allow-methods', 'GET,HEAD,PUT,POST,DELETE,OPTIONS');
/*
  response: {
    status: 200,
    message: 'OK',
    header: [Object: null prototype] {
      'access-control-allow-credentials': 'true',
      'access-control-allow-origin': 'http://localhost:3001',
      'access-control-allow-headers': 'content-type,authorization,accept,accept-language',
      'access-control-allow-methods': 'GET,HEAD,PUT,POST,DELETE,OPTIONS'
    }
  }
*/

Using the new apollo server integration, cors requests are failing here, and introspection queries from different hosts fail

app.js

const apolloServer = new ApolloServer({
  schema: executableSchema,
  formatError: (formattedError, error) => ({
    console.log(error.extensions.http.headers) // { status: 400, headers: HeaderMap(0) [Map] {} }
    console.log(error)
    // BadRequestError [GraphQLError]: This operation has been blocked as a potential
    // Cross-Site Request Forgery (CSRF). Please either specify a 'content-type' header
    // (with a type that is not one of application/x-www-form-urlencoded,
    // multipart/form-data, text/plain) or provide a non-empty value for one of the
    // following headers: x-apollo-operation-name, apollo-require-preflight
    return formattedError;
  })
})

thanks for any reply you may give

@iambumblehead
Copy link
Author

iambumblehead commented Jan 10, 2023

This allows custom cors behaviour with Apollo4,

  • middleware setting cors headers must be attached before koaMiddleware app.use(koaMiddleware(apolloServer, { /* ...options */ });,
  • middleware must call koa's downstream middleware with next(), before headers are attached
    • calling 'next()' only necessary when request type is not 'OPTIONS'
    • calling 'next()' before headers are defined for any request also succeeds, so that is what is done below

I experimented with a few other arrangements, such as cors after koaMiddleware etc this was the only arrangement that succeeded here using apollo4

app.use(async (ctx, next) => {
  // apollo4 downstream must process first before headers attached
  if (apollo4Koa) await next();

  ctx = attachCorsHeaders(ctx);

  return ctx;
});

Something like this seems to be happening. Problematic cors behaviour is not found by Apollo4 developers, because Apollo4 is tested with @koa/cors, which always calls next() when request method is not OPTIONS. If cors headers are attached before the Apollo4 middleware are run, Apollo removes the headers or has some other problem. The apollo middleware must run last, forcing cors middleware do be attached before apollo.

@matthew-gordon
Copy link
Collaborator

I am a little busy this week but will try and look into this more, in the mean time please feel free to open a PR they are more than welcome!

@trevor-scheer
Copy link
Member

@iambumblehead I don't quite follow what your exact issue is. This seems relevant but I can't quite piece together what the actual problem is:

because Apollo4 is tested with @koa/cors, which always calls next() when request method is not OPTIONS. If cors headers are attached before the Apollo4 middleware are run, Apollo removes the headers or has some other problem. The apollo middleware must run last, forcing cors middleware do be attached before apollo.

Are you suggesting that @koa/cors is doing the wrong thing? Are we testing the integration incorrectly in some way? Can you share a reproduction that demonstrates the issue clearly? We have a codesandbox which makes for a good jumping off point if that's helpful: https://codesandbox.io/s/apollo-server-typescript-3opde?file=/src/index.ts (you'll have to add the Koa bits).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants