NextAuth返回的JWT无用户数据问题求助
解决NextAuth JWT不包含用户数据的问题
你的问题出在两个核心点:authorize方法的返回结构错误,以及缺少JWT和Session回调配置,导致用户数据没有被正确注入到JWT和Session中。
问题分析
authorize方法返回的是嵌套在user对象里的属性,但NextAuth期望直接返回用户字段(如email、firstName),而非嵌套结构。- 使用
jwt会话策略时,NextAuth不会自动将自定义用户字段加入JWT,必须通过jwt和session回调手动处理数据传递。
修改后的完整代码
import Credentials from 'next-auth/providers/credentials'; import { NextAuthOptions } from 'next-auth'; import { verifyPassword } from '../../../lib/auth'; import { connectToDatabase } from '../../../lib/db'; export default NextAuth({ session: { strategy: 'jwt', }, providers: [ Credentials({ async authorize(credentials: Record<string, string> | undefined) { if (!credentials) { throw new Error('Credentials not defined.'); } let client; try { client = await connectToDatabase(); const usersCollection = client .db(process.env.DB_DB) .collection('account'); const user = await usersCollection.findOne({ email: credentials.email, }); if (!user) { throw new Error('No user found.'); } const isValid = await verifyPassword( credentials.password, user.password ); if (!isValid) { throw new Error('Your password is incorrect.'); } // 直接返回用户字段,不要嵌套在user对象里 return { email: user.email, firstName: user.firstName, lastName: user.lastName, }; } finally { // 用finally确保无论是否出错都关闭数据库连接 if (client) client.close(); } }, credentials: {}, }), ], // 添加JWT回调:将用户数据注入JWT callbacks: { async jwt({ token, user }) { // 用户登录时,user会包含authorize返回的字段 if (user) { token.email = user.email; token.firstName = user.firstName; token.lastName = user.lastName; } return token; }, // 添加Session回调:从JWT中提取数据到Session async session({ session, token }) { if (session.user) { session.user.email = token.email as string; session.user.firstName = token.firstName as string; session.user.lastName = token.lastName as string; } return session; }, }, pages: { signIn: '/', }, });
关键修改点说明
- 修正authorize返回结构:直接返回
{email, firstName, lastName},而非嵌套的user对象,这样NextAuth才能正确识别用户数据。 - 添加jwt回调:在用户登录时(
user存在),将用户字段附加到JWT token中,后续请求会携带这些数据。 - 添加session回调:从JWT token中提取用户数据,赋值给
session.user,这样getSession()就能拿到完整的用户信息。 - 优化数据库连接关闭:用
try/finally确保数据库连接无论是否出错都会关闭,避免资源泄漏。
修改后,调用getSession()就能获取到包含email、firstName、lastName的完整user对象了。
内容的提问来源于stack exchange,提问作者bencrow11
相关产品推荐
相关产品推荐

