问题
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 tho the docs make this look like a straightforward migration I does't seem to make it work. I've checked various articles and no one seems to be having the issue.
Hope you guys can help me.
Cheers!
回答1:
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
}
// not needed, CORS middleware is applied
// using the Apollo Server's middleware API
// 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 })
});
// no need to explicitly define 'path' option in object
// as '/graphql' is the default endpoint
server.applyMiddleware({ app, cors: corsOptions });
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
})
回答2:
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
来源:https://stackoverflow.com/questions/54485239/apollo-server-express-cors-issue