问题描述
所以我正在迁移到Apollo-Server-express 2.3.3(我使用的1.3.6) 我遵循了几个指南,进行了必要的调整,但陷入了CORS问题.
根据 docs 您必须使用applymiddleware函数将Apollo服务器与Express.
连接起来.我目前正在执行以下操作:
const app = express(); // CORS configuration const corsOptions = { origin: 'http://localhost:3000', credentials: true } app.use(cors(corsOptions)) // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); server.applyMiddleware({ app }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
由于某种原因,当我尝试从Localhost发出请求时,我的Express中间件似乎没有执行:3000(客户端应用程序),我会得到典型的CORS错误
使用Apollo-Server-express 1.3.6我没有任何问题.
app.use( '/graphql', graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }), bodyParser.json(), graphqlExpress(({ currentUser }) => ({ schema, context: { // Pass Mongoose models Property, User, currentUser } })) );
现在有了新版本,尽管文档使它看起来像是一个直接的迁移,但我似乎无法使其正常工作.我已经检查了各种文章,似乎没有人遇到问题.
推荐答案
从我对阿波罗服务器的理解https://www.apollographql.com/docs/apollo-server/api/api/api/api/api--server#apolloservelpolloserapplymiddleware到,CORS选项,Body-Parser选项和GraphQL端点被视为必须直接传递到applyMiddleware param对象的特殊实体.
因此,您想尝试以下配置:
const app = express(); // CORS configuration const corsOptions = { origin: 'http://localhost:3000', credentials: true } // The following is not needed, CORS middleware will be applied // using the Apollo Server's middleware API (see further below) // app.use(cors(corsOptions)) // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); // There is no need to explicitly define the 'path' option in // the configuration object as '/graphql' is the default endpoint // If you planned on using a different endpoint location, // this is where you would define it. server.applyMiddleware({ app, cors: corsOptions }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
其他推荐答案
使用Apollo Server 2.x,您在ApolloServer的构造函数中提供cors字段.
因此,在您的情况下,它应该看起来如下:
const corsOptions = { origin: 'http://localhost:3000', credentials: true } // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, cors: cors(corsOptions), resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); server.applyMiddleware({ app }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
在这里,您可以找到Apollo服务器接受的所有参数: https://www.apolloghth.apolloghth.com/docs/Pollo-Server/API/APOLLO-SERVER.HTML#PARAMETERS-2
在这里您找到相关讨论: https://github.com/apollographqulographql/apollographql/apollo-server/1142/1142
其他推荐答案
CORS设置来自ExpressJS,而不是来自Apolloserver.如果要添加自定义或通配符来源,则必须使用回调/处理程序函数来处理它.
const server = new ApolloServer({ ...., cors: { credentials: true, origin: (origin, callback) => { const whitelist = [ "http://site1.com", "https://site2.com" ]; if (whitelist.indexOf(origin) !== -1) { callback(null, true) } else { callback(new Error("Not allowed by CORS")) } } } });
问题描述
So I am migrating to apollo-server-express 2.3.3 ( I was using 1.3.6 ) I've followed several guides, making the necessary tweaks but am stuck in a CORS issue.
According to the docs you have to use the applyMiddleware function to wire up the apollo server with express.
I am currently doing the following:
const app = express(); // CORS configuration const corsOptions = { origin: 'http://localhost:3000', credentials: true } app.use(cors(corsOptions)) // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); server.applyMiddleware({ app }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
For some reason my express middleware doesn't seem to be executing, when I try to do a request from localhost:3000 (client app) I get the typical CORS error
With apollo-server-express 1.3.6 I was doing the following without no issues:
app.use( '/graphql', graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }), bodyParser.json(), graphqlExpress(({ currentUser }) => ({ schema, context: { // Pass Mongoose models Property, User, currentUser } })) );
Now with the new version, event though the docs make this look like a straightforward migration, I don't seem to be able to make it work. I've checked various articles and no one seems to be having the issue.
推荐答案
From my understanding of the Apollo Server middleware API, CORS options, body-parser options and the graphql endpoint are treated as special entities that must be passed directly to the applyMiddleware param object.
So you want to try the following configuration:
const app = express(); // CORS configuration const corsOptions = { origin: 'http://localhost:3000', credentials: true } // The following is not needed, CORS middleware will be applied // using the Apollo Server's middleware API (see further below) // app.use(cors(corsOptions)) // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); // There is no need to explicitly define the 'path' option in // the configuration object as '/graphql' is the default endpoint // If you planned on using a different endpoint location, // this is where you would define it. server.applyMiddleware({ app, cors: corsOptions }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
其他推荐答案
With Apollo Server 2.x you supply the cors field in the constructor of ApolloServer.
So in your case, it should look like the following:
const corsOptions = { origin: 'http://localhost:3000', credentials: true } // Setup JWT authentication middleware app.use(async (req, res, next) => { const token = req.headers['authorization']; if(token !== "null"){ try { const currentUser = await jwt.verify(token, process.env.SECRET) req.currentUser = currentUser } catch(e) { console.error(e); } } next(); }); const server = new ApolloServer({ typeDefs, cors: cors(corsOptions), resolvers, context: ({ req }) => ({ Property, User, currentUser: req.currentUser }) }); server.applyMiddleware({ app }); const PORT = process.env.PORT || 4000; app.listen(PORT, () => { console.log(`Server listening on ${PORT}`); })
Here you find all params accepted by the apollo server: https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2
Here you find the relevant discussion: https://github.com/apollographql/apollo-server/issues/1142
其他推荐答案
The CORS settings come from ExpressJS, not from ApolloServer. If you want to add a custom or wildcard origin you have to handle it with a callback/handler function.
const server = new ApolloServer({ ...., cors: { credentials: true, origin: (origin, callback) => { const whitelist = [ "http://site1.com", "https://site2.com" ]; if (whitelist.indexOf(origin) !== -1) { callback(null, true) } else { callback(new Error("Not allowed by CORS")) } } } });