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

NextAuth JWT回调中user对象为空的问题排查求助

NextAuth JWT回调user参数为undefined问题排查

我正在调整NextAuth的JWT与Session回调,想给浏览器会话附加属性,但JWT回调里的user参数一直是undefined。当前用的是JWT会话策略和自定义登录页面,以下是相关日志、authorize方法及回调代码:

JWT和Session回调日志

JWT Callback {
  token: {
    name: 'John Doe',
    email: 'test@test.com',
    iat: 1678918901,
    exp: 1681511921,
    jti: '4e1b6c12-68f0-4009-8497-b2fa6a3bbb7e'
  },
  user: undefined
}
Session Callback {
  session: {
    user: { name: 'John Doe', email: 'test@test.com', image: undefined },
    expires: '2023-04-14T22:26:51.318Z'
  },
  token: {
    name: 'John Doe',
    email: 'test@test.com',
    iat: 167891221,
    exp: 1682510921,
    jti: '4e1b6c12-68f0-4009-8497-b2fa6a3bbb7e'
  }
}

authorize方法代码

async authorize(credentials) {
        console.log(credentials);
        const email = credentials.email;
        const password = credentials.password;
        const formPassword = credentials.formPassword;
        const authFormType = credentials.newUser ? formPassword : password;

        try {
          if (!email || !password) {
            console.log('No Email or Password Provided');
            return null;
          }

          const user = await prisma.appUsers.findUnique({
            where: {
              email: email,
            },
          });

          if (!user) {
            console.log('User does not exist');
            return null;
          }

          const isPasswordValid = await confirmPasswordHash(
            authFormType,
            user.password
          );

          if (!isPasswordValid) {
            console.log('Password is not correct');
            return null;
          }

          return {
            email: user.email,
            name: user.firstName + ' ' + user.lastName,
            // id: user.id,
            // newUser: credentials.newUser,
          };
        } catch (error) {
          console.log(`Error: ${error}`);
        }
      },

回调配置代码

callbacks: {
    session: ({ session, token }) => {
      console.log('Session Callback', { session, token });
      return session;
    },
    jwt: ({ token, user }) => {
      console.log('JWT Callback', { token, user });
      if (user) {
        // console.log('user', user);
      }
      return token;
    },
  },

问题原因及解决办法

  1. JWT回调执行逻辑:JWT回调分两次触发:

    • 首次登录成功时:user参数会携带authorize返回的用户对象,此时可以把自定义属性附加到token中
    • 后续会话验证时:user为undefined,因为系统直接解析已有JWT令牌,不会再调用authorize
      你的日志显示当前是后续验证场景,所以user为undefined是正常现象。
  2. 修改JWT回调,首次登录时附加属性:
    调整JWT回调代码,仅在user存在时(首次登录)将自定义属性写入token:

    jwt: ({ token, user }) => {
      console.log('JWT Callback', { token, user });
      if (user) {
        token.id = user.id;
        token.newUser = user.newUser;
      }
      return token;
    },
    
  3. 完善authorize返回值:
    取消注释authorize方法中返回对象的id和newUser字段,确保这些属性能传递到JWT回调:

    return {
      email: user.email,
      name: user.firstName + ' ' + user.lastName,
      id: user.id,
      newUser: credentials.newUser,
    };
    
  4. Session回调同步属性到前端:
    在Session回调中把token里的自定义属性同步到session对象,让前端能访问到:

    session: ({ session, token }) => {
      console.log('Session Callback', { session, token });
      session.user.id = token.id;
      session.user.newUser = token.newUser;
      return session;
    },
    

内容的提问来源于stack exchange,提问作者cphill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:33:18