簡體   English   中英

阿波羅服務器快遞 CORS 問題

[英]apollo-server-express CORS issue

所以我正在遷移到 apollo-server-express 2.3.3 (我使用的是 1.3.6 )我遵循了幾個指南,進行了必要的調整,但陷入了 CORS 問題。

根據文檔,您必須使用 applyMiddleware function 將 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: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
        }
    }))
);

現在有了新版本,盡管文檔使這看起來像一個簡單的遷移,但我似乎無法使其工作。 我檢查了各種文章,似乎沒有人遇到問題。

根據我對 Apollo Server 中間件 API 的理解,CORS 選項、body-parser 選項和 graphql 端點被視為必須直接傳遞給applyMiddleware參數對象的特殊實體。

所以你想嘗試以下配置:

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}`);
})

與阿波羅服務器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}`);
})

在這里您可以找到 apollo 服務器接受的所有參數: https : //www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2

在這里你可以找到相關的討論: https : //github.com/apollographql/apollo-server/issues/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"))
            }
        }
    }
});

默認情況下,express 中間件將使用 graphql 路徑上的默認選項實例化 cors 中間件,覆蓋您自己為其他路徑指定的任何 cors 中間件配置(!)

您可以在應用 apollo 中間件時覆蓋默認值,例如

apollo.applyMiddleware({ app, cors: {credentials: true, origin: true} })

我正在使用 apollo-server-express 2.17

只需刪除 csrfPrevention: true 並且您對 go 很好

 import { ApolloServer } from 'apollo-server-express'; import { ApolloServerPluginDrainHttpServer } from 'apollo-server-core'; import express from 'express'; import http from 'http'; async function startApolloServer(typeDefs, resolvers) { // Required logic for integrating with Express const app = express(); // Our httpServer handles incoming requests to our Express app. // Below, we tell Apollo Server to "drain" this httpServer, // enabling our servers to shut down gracefully. const httpServer = http.createServer(app); // Same ApolloServer initialization as before, plus the drain plugin // for our httpServer. const server = new ApolloServer({ typeDefs, resolvers, csrfPrevention: true, cache: 'bounded', plugins: [ApolloServerPluginDrainHttpServer({ httpServer })], }); // More required logic for integrating with Express await server.start(); server.applyMiddleware({ app, // By default, apollo-server hosts its GraphQL endpoint at the // server root. However, *other* Apollo Server packages host it at // /graphql. Optionally provide this to match apollo-server. path: '/', }); // Modified server startup await new Promise(resolve => httpServer.listen({ port: 4000 }, resolve)); console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM