我有一个 Next.js 项目,我使用 next-auth 进行授权。
说明情况:
我有一个用户列表,因此当我单击卡片时,它会使用 setContext 将请求发送到服务器,该服务器为每个请求传递一个用户令牌,但我收到了这样的错误:
ApolloError: Invariant: Method expects to have requestAsyncStorage, none available
但是当我从服务器获取用户时没有问题,并且令牌工作正常。
我尝试了什么?:
我浪费了很多时间试图找到答案,但没有一个答案对我有帮助。
另外,我尝试删除“getServerSession”,并在 setContext 标头中手动设置令牌,并且它开始正常工作,没有错误。
所以最后我认为问题出在“getServerSession”中,但是我如何从cookie中获取令牌?
“getSession”不是服务器端函数,所以它没有给我任何东西。
资源:
所以,这是一个“apollo-client.ts”代码,我在其中使用“setContext”
const wsLink =
typeof window !== "undefined"
? new GraphQLWsLink(
createClient({
url: "ws://localhost:5000/subscriptions",
})
)
: null;
const httpLink = createHttpLink({
uri: "http://localhost:5000/",
credentials: "same-origin",
});
const link =
typeof window !== "undefined" && wsLink != null
? split(
({ query }) => {
const def = getMainDefinition(query);
return (
def.kind === "OperationDefinition" &&
def.operation === "subscription"
);
},
wsLink,
httpLink
)
: httpLink;
const authLink = setContext((_, { headers }) => {
return getServerSession(authOptions).then((el) => {
return {
headers: {
...headers,
authorization: el ? `Bearer ${el?.accessToken}` : "",
},
};
});
});
const cache = new InMemoryCache();
const client = new ApolloClient({
link: authLink.concat(link),
cache: cache,
uri: "http://localhost:5000/",
credentials: "include",
});
export default client;
您正在全局模块范围内创建客户端、链接等 - 这意味着您创建一个 ApolloClient 实例,该实例将在服务器看到的所有用户和请求之间共享。当使用像 Next.js 这样的 SSR 框架时,你绝对不应该这样做。
这也是您看到此错误的原因 -
getServerSession
想要访问当前请求,但您在任何请求之外的上下文中调用它。
相反,创建一个创建新 Apollo 客户端的函数,并通过调用它为每个请求创建一个新实例。几乎所有您能找到的“Apollo Client 和 Next.js”指南都应该显示这种模式。
您无法使用 Next.js 应用模块范围 Apollo 客户端实例的仅客户端模式。