Can’t get CORS working with Restify + GraphQL setup

I’ve set up a GraphQL server using express-graphql and Restify, which works perfectly on Postman. However, when actually calling it from our frontend we keep getting CORS issues. I’ve tried just about everything.

The weird thing is that if we remove all headers from the frontend axios request, CORS is no longer an issue – but then we get the “query must be a string” error from graphql.

Full code:

const restify = require('restify');
const { graphqlHTTP } = require('express-graphql');
const corsMiddleware = require('restify-cors-middleware2');

const schema = require('./Schemas');
const { auth } = require('./middleware');
const { bugsnag } = require('./utils/config');

const PORT = process.env.PORT || 3004;
const app = restify.createServer();

app.use(bugsnag.requestHandler);

app.use(function crossOrigin(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    const allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version', 'Origin', 'X-Requested-With']; // added Origin & X-Requested-With

    res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
    // res.header('Access-Control-Allow-Credentials', true); // tried both with and without this
    return next();
});

app.use(auth.authenticateUser);

app.post(
    '/graph',
    graphqlHTTP((req, res, graphQLParams) => {
        console.log(req);
        return {
            schema,
            context: {
                user: req.user,
            },
        };
    })
);

app.get(
    '/graph',
    graphqlHTTP({
        schema,
        graphiql: true,
    })
);

app.listen(PORT, () => console.log(`Listening on port ${PORT}!`));

Other things I’ve tried:

const cors = corsMiddleware({
    preflightMaxAge: 5,
    origins: ['*'],
    allowHeaders: ['X-App-Version'],
    exposeHeaders: [],
});
app.pre(cors.preflight);
app.use(cors.actual);

I also tried:

app.use(function crossOrigin(req, res, next) {
    console.log('Adding cors headers');
    const allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version', 'Origin', 'X-Requested-With']; 
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
    res.header("Access-Control-Allow-Origin", "http://localhost:3000");
    next();
});

I also tried basically every combination of all of the above, and none worked. I even tried removing the auth header from the request and removing the auth middleware, and that didn’t work either (although it did get us to the point where at least it was a 404 error due to “query not being a string” rather than the CORS issue.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

This isn’t very well documented in the restify-cors-middleware2 package, but turns out I need to set the allowCredentialsAllOrigins and credentials properties, as well as add a lot more allowHeaders:

const cors = corsMiddleware({
    preflightMaxAge: 5,
    origins: ['*'],
    allowHeaders: [
        'X-App-Version',
        'Accept',
        'Accept-Version',
        'Content-Type',
        'Api-Version',
        'Origin',
        'X-Requested-With',
        'Authorization',
    ],
    exposeHeaders: [],
    credentials: true,
    allowCredentialsAllOrigins: true,
});
app.pre(cors.preflight);
app.use(cors.actual);


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x