You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth集成GoogleProvider时session回调无法获取用户信息

问题分析与解决方案

核心问题

你的问题出在Session策略未显式配置以及JWT回调未完整保留用户信息,导致Session回调中无法正确获取用户邮箱等数据,最终客户端useSession拿不到有效信息。

具体修复步骤

1. 显式配置Session策略为JWT

当使用MongoDB Adapter时,NextAuth默认会采用database Session策略,这会导致JWT回调仅在首次登录时触发,后续请求的Session数据直接从数据库读取,此时你的Session回调中直接将session.user赋值为token会出现数据缺失或undefined。

需要在authOptions中添加session配置:

session: {
  strategy: "jwt", // 强制使用JWT策略,确保JWT和Session回调协同工作
  maxAge: 30 * 24 * 60 * 60, // 可选:设置Session有效期,默认30天
},

2. 完善JWT回调,保留完整用户信息

你的JWT回调仅添加了accessToken和id,但未将用户的邮箱、名称等核心信息存入Token,导致后续Session回调中Token没有这些数据。修改JWT回调:

async jwt({ token, account, user }) {
  // 首次登录时(account和user存在),将用户信息合并到Token
  if (account && user) {
    return {
      ...token,
      id: user.id,
      email: user.email,
      name: user.name,
      picture: user.picture,
      accessToken: await SignToken(user.email as string),
    };
  }
  // 非首次登录,直接返回现有Token
  return token;
},

3. 修正Session回调,正确映射用户数据

不要直接将session.user替换为token,而是将Token中的字段逐一映射到session.user,保证Session结构符合NextAuth的默认规范:

async session({ session, token }) {
  if (session.user) {
    // 将Token中的用户信息赋值给Session.user
    session.user.id = token.id as string;
    session.user.email = token.email as string;
    session.user.name = token.name as string;
    session.user.picture = token.picture as string;
    session.user.accessToken = token.accessToken as string;
  }
  return session;
},

4. 可选:确保GoogleProvider权限范围正确

虽然默认情况下GoogleProvider会请求email和profile权限,但显式声明可以避免权限缺失问题:

GoogleProvider({
  clientId: process.env.GOOGLE_CLIENT_ID!!,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET!!,
  authorization: {
    params: {
      scope: "openid email profile", // 显式请求邮箱和基础资料权限
    },
  },
})

完整修正后的服务端代码

export const authOptions: NextAuthOptions = {
  adapter: MongoDBAdapter(clientPromise),
  // 新增Session策略配置
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60,
  },
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!!,
      authorization: {
        params: {
          scope: "openid email profile",
        },
      },
    }),
  ],
  callbacks: {
    async jwt({ token, account, user }) {
      if (account && user) {
        return {
          ...token,
          id: user.id,
          email: user.email,
          name: user.name,
          picture: user.picture,
          accessToken: await SignToken(user.email as string),
        };
      }
      return token;
    },
    async session({ session, token }) {
      if (session.user) {
        session.user.id = token.id as string;
        session.user.email = token.email as string;
        session.user.name = token.name as string;
        session.user.picture = token.picture as string;
        session.user.accessToken = token.accessToken as string;
      }
      return session;
    },
  },
};

验证结果

修改后重新启动服务,客户端通过useSession获取的session.user会包含email、id、name等完整信息,控制台输出的session数据也会正常显示用户邮箱。

内容的提问来源于stack exchange,提问作者Captai-N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:43:28