在 Apollo Server 上下文中获取 NextAuth.js 用户会话

Posted

技术标签:

【中文标题】在 Apollo Server 上下文中获取 NextAuth.js 用户会话【英文标题】:Getting NextAuth.js user session in Apollo Server context 【发布时间】:2021-04-24 06:48:52 【问题描述】:

我的网络应用正在使用:

NextJS NextAuth.js 阿波罗服务器

我在我的应用中设置了 NextAuth,我可以正常登录。

问题来自于试图在 Apollo 上下文中访问用户会话。我想将我的用户会话传递给每个解析器。这是我当前的代码:

import  ApolloServer, AuthenticationError  from "apollo-server-micro";
import schema from "./schema";
import mongoose from "mongoose";
import dataloaders from "./dataloaders";
import  getSession  from "next-auth/client";

let db;

const apolloServer = new ApolloServer(
  schema,
  context: async ( req ) => 
    /*
    ...

    database connection setup
    
    ...
    */

    // get user's session
    const userSession = await getSession( req );
    console.log("USER SESSION", userSession); // <-- userSession is ALWAYS null


    if (!userSession) 
      throw new AuthenticationError("User is not logged in.");
    

    return  db, dataloaders, userSession ;
  ,
);

export const config = 
  api: 
    bodyParser: false,
  ,
;

export default apolloServer.createHandler( path: "/api/graphql" );

问题是,会话 (userSession) 始终为空,即使我已登录(并且可以从适当的 NextJS API 路由中很好地获取会话)。我的猜测是,因为用于获取会话的 NextAuth 函数,getSession( req ) 正在传递 req——这是由 Apollo Server Micro 提供的,而不是来自 NextJS(NextAuth 所期望的)。我做了很多搜索,找不到遇到同样问题的人。非常感谢任何帮助!

【问题讨论】:

如果有人在使用 Auth0 + graphql 时发生这种情况: import getSession from '@auth0/nextjs-auth0' context: async args => const session = await getSession(args.req) return 用户: session.user 那么也许您尝试不将req 作为对象传递,而是直接传递? const userSession = await getSession( req ) 【参考方案1】:

我确实遇到了这个问题,我发现这是因为 Apollo GraphQL 游乐场。

没有"request.credentials": "include",游乐场不会发送凭据。

我的 NextAuth / GraphQL API 如下所示:

import  ApolloServer  from "apollo-server-micro";
import  getSession  from "next-auth/client";
import  typeDefs, resolvers  "./defined-elsewhere"

const apolloServer = new ApolloServer(
  typeDefs,
  resolvers,
  context: async ( req ) => 
    const session = await getSession( req );
    return  session ;
  ,
  playground: 
    settings: 
      "editor.theme": "light",
      "request.credentials": "include",
    ,
  ,
);

希望这对你有用!

【讨论】:

您介意分享您的完整代码吗?我仍然无法获得req。 .createHandler时有没有设置选项?【参考方案2】:

我刚刚遇到了类似的事情。我不能 100% 确定,因为很难知道确切的细节,因为您上面的示例代码没有显示您是如何从客户端与 apollo 进行交互的会话作为空值通过之前。不过,我相信您可能正在从 getStaticProps 内部进行 API 调用,这会导致静态代码生成并在 构建时间 运行 - 即当可能不存在此类用户上下文/会话时。

见https://github.com/nextauthjs/next-auth/issues/383

The getStaticProps method in Next.js is only for build time page generation (e.g. for generating static pages from a headless CMS) and cannot be used for user specific data such as sessions or CSRF Tokens.

另外,我不确定你为什么被否决 - 即使答案主要是标准 rtm ,问 imo 似乎也是一个合法的问题 :)。我以前也在这里发生过——你赢了一些,你输了一些:)干杯

【讨论】:

嘿,谢谢!我没想到会得到答案 :) 考虑到这一点,我会进一步调查并报告。 别担心 - 我希望它会有所帮助:)

以上是关于在 Apollo Server 上下文中获取 NextAuth.js 用户会话的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Apollo Server 中正确键入上下文对象?

req 在 Apollo Server 上下文中始终未定义

使用 ExpressJS 访问 Apollo Server 中的 Request 对象

升级到 apollo-server-express 2.0.0 缺少上下文

Apollo Server:如何从 REST API 数据源访问 Dataloader 中解析器之外的“上下文”

使用 graphql 和 apollo-server 在解析器中获取会话