阿波罗服务器快递CORS问题

Jos*_*lle 4 node.js express graphql apollo-server

因此,我要迁移到apollo-server-express 2.3.3(我使用的是1.3.6),我遵循了一些指南,进行了必要的调整,但陷入了CORS问题。

根据文档,您必须使用applyMiddleware函数通过express连接apollo服务器。

我目前正在执行以下操作:

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}`);
})
Run Code Online (Sandbox Code Playgroud)

由于某种原因,我的中间件似乎没有执行,当我尝试从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
        }
    }))
);
Run Code Online (Sandbox Code Playgroud)

现在有了新版本,文档中的事件使此操作看起来像一个简单的迁移,我似乎并没有使它起作用。我检查了各种文章,似乎没有人遇到这个问题。

希望你们能帮助我。

干杯!

Jax*_*axx 12

根据我对Apollo Server 中间件API的理解,CORS选项,body-parser选项和graphql端点被视为必须直接传递给applyMiddlewareparam对象的特殊实体。

因此,您想尝试以下配置:

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}`);
})
Run Code Online (Sandbox Code Playgroud)

  • 我认为这应该是公认的答案。这是唯一对我有用的答案。 (2认同)
  • @KarelFrajták要清楚,我没有提到该软件包的需要,因为OP表示他使用的是`apollo-server-express`,它提供了方法 (2认同)

小智 8

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"))
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


flu*_*lup 8

默认情况下,express 中间件将使用 graphql 路径上的默认选项实例化 cors 中间件,覆盖您自己为其他路径指定的任何 cors 中间件配置(!)

当您应用apollo中间件时,您可以覆盖默认值,例如

apollo.applyMiddleware({ app, cors: {credentials: true, origin: true} })
Run Code Online (Sandbox Code Playgroud)

我正在使用 apollo-server-express 2.17


Ric*_*ic0 5

使用 Apollo Server 2.x,您可以corsApolloServer.

所以在你的情况下,它应该如下所示:

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}`);
})
Run Code Online (Sandbox Code Playgroud)

在这里您可以找到 apollo 服务器接受的所有参数:https : //www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2

在这里你可以找到相关的讨论:https : //github.com/apollographql/apollo-server/issues/1142