所以我要迁移到apollo-server-express 2.3.3(我使用的是1.3.6) 我遵循了一些指南,进行了必要的调整,但陷入了CORS问题。
根据docs,您必须使用applyMiddleware函数将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: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
}
}))
);
现在有了新版本,文档中的事件使它看起来像是一个简单的迁移,我似乎并没有使它起作用。我检查了各种文章,似乎没有人遇到这个问题。
希望你们能帮助我。
干杯!
答案 0 :(得分:6)
根据我对Apollo服务器middleware API的理解,CORS选项,主体分析器选项和graphql端点被视为必须直接传递到applyMiddleware
参数对象的特殊实体。
因此,您想尝试以下配置:
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}`);
})
答案 1 :(得分:3)
在Apollo Server 2.x中,您需要在cors
的构造函数中提供ApolloServer
字段。
因此,在您的情况下,它应如下所示:
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}`);
})
在这里找到阿波罗服务器接受的所有参数: https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2
在这里您找到相关的讨论: https://github.com/apollographql/apollo-server/issues/1142
答案 2 :(得分:2)
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"))
}
}
}
});
答案 3 :(得分:1)
默认情况下,快速中间件将使用graphql路径上的默认选项实例化cors中间件,从而覆盖您自己为其他路径指定的任何cors中间件配置(!)
例如,当您应用阿波罗中间件时,您可以覆盖默认设置。
apollo.applyMiddleware({ app, cors: {credentials: true, origin: true} })
我正在使用apollo-server-express 2.17