我在不同的存储库和不同的域下有两个 NextJS 应用程序。
我希望第二个 NextJS 应用程序获取第一个 NextJS 应用程序的后端代码。后端是graphql + apollo。但我遇到了“访问控制允许来源”问题,因为它们的域不匹配。
这是一个图表来说明我的设置。解决这个问题的最佳实践是什么?两个 UI、两个域、一个后端。
在本地主机上,它运行良好。
应用程序A:本地主机:3000 应用程序 B: localhost:4000
对于应用程序 B,NEXT_PUBLIC_APOLLO_BASE_URL 为“localhost:3000”。但是当切换到托管域时,就会出现 CORS 问题
import {
ApolloClient,
ApolloClientOptions,
InMemoryCache,
NormalizedCacheObject,
createHttpLink,
} from '@apollo/client'
import { auth } from 'app/firebase/clientApp'
import { setContext } from '@apollo/client/link/context'
//import { offsetLimitPagination } from "@apollo/client/utilities";
//
//
const apolloCache = new InMemoryCache({
typePolicies: {
SearchConfigOption: {
keyFields: ['pathName'],
},
Query: {
fields: {
/* filterItems: {
keyArgs: ['user'],
merge(existing, incoming) {
if (!incoming) return existing
if (!existing) return incoming // existing will be empty the first time
const { items, ...rest } = incoming
let result = rest
result.items = [...existing.items, ...items] // Merge existing items with the items from incoming
return result
},
},*/
},
},
},
})
const httpLink = createHttpLink({
uri: `${process.env.NEXT_PUBLIC_APOLLO_BASE_URL}api/graphql`,
credentials: 'include',
})
const authLink = setContext(async (_, { headers }) => {
const user = auth.currentUser
const token = user && (await user.getIdToken())
const modifiedHeader = {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : 'Bearer null',
},
}
return modifiedHeader
})
const client = new ApolloClient({
ssrMode: typeof window === 'undefined',
link: authLink.concat(httpLink),
cache: apolloCache,
connectToDevTools: process.env.NODE_ENV !== 'production',
credentials: 'include',
})
export default client
这里的问题是你必须在后端 CORS 中间件中配置应用程序 B 的域,如果你的后端使用 Express 服务器,这就是你的配置方式
const express = require('express');
const cors = require('cors');
const { ApolloServer } = require('apollo-server-express');
const app = express();
const corsOptions = {
origin: ['https://merchant-domain.com', "https://application-2-domain.com"],
credentials: true,
};
app.use(cors(corsOptions));
const server = new ApolloServer({
// Apollo server configuration
});
server.applyMiddleware({ app, path: '/api/graphql', cors: false });
app.listen({ port: 3000 }, () =>
console.log(`Server ready at http://localhost:3000${server.graphqlPath}`)
);