无法让 CORS 使用 Restify + GraphQL 设置
Can't get CORS working with Restify + GraphQL setup
我已经使用 express-graphql 和 Restify 设置了一个 GraphQL 服务器,它在 Postman 上完美运行。然而,当实际从我们的前端调用它时,我们不断遇到 CORS 问题。我几乎什么都试过了。
奇怪的是,如果我们从前端 axios 请求中删除所有 headers,CORS 不再是一个问题 - 但随后我们从 graphql 中得到“查询必须是字符串”错误。
完整代码:
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}!`));
我尝试过的其他事情:
const cors = corsMiddleware({
preflightMaxAge: 5,
origins: ['*'],
allowHeaders: ['X-App-Version'],
exposeHeaders: [],
});
app.pre(cors.preflight);
app.use(cors.actual);
我也试过:
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();
});
我也基本上尝试了上述所有组合,并且 none 奏效了。我什至尝试从请求中删除 auth header 并删除 auth 中间件,但这也不起作用(尽管它确实让我们达到了至少是 404 错误的地步,因为“查询不是字符串”而不是 CORS 问题。
这在 restify-cors-middleware2
包中没有很好的记录,但事实证明我需要设置 allowCredentialsAllOrigins
和 credentials
属性,以及添加更多 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);
我已经使用 express-graphql 和 Restify 设置了一个 GraphQL 服务器,它在 Postman 上完美运行。然而,当实际从我们的前端调用它时,我们不断遇到 CORS 问题。我几乎什么都试过了。
奇怪的是,如果我们从前端 axios 请求中删除所有 headers,CORS 不再是一个问题 - 但随后我们从 graphql 中得到“查询必须是字符串”错误。
完整代码:
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}!`));
我尝试过的其他事情:
const cors = corsMiddleware({
preflightMaxAge: 5,
origins: ['*'],
allowHeaders: ['X-App-Version'],
exposeHeaders: [],
});
app.pre(cors.preflight);
app.use(cors.actual);
我也试过:
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();
});
我也基本上尝试了上述所有组合,并且 none 奏效了。我什至尝试从请求中删除 auth header 并删除 auth 中间件,但这也不起作用(尽管它确实让我们达到了至少是 404 错误的地步,因为“查询不是字符串”而不是 CORS 问题。
这在 restify-cors-middleware2
包中没有很好的记录,但事实证明我需要设置 allowCredentialsAllOrigins
和 credentials
属性,以及添加更多 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);