如何在NextAuth的Session中返回MongoDB的_id?
NextAuth 添加 MongoDB 用户 ID 到会话的实现方案
你的理解完全正确:jwt 回调返回的 token 会被 session 回调接收,用来生成最终返回给前端/服务端的会话对象。
先理清楚 authorize、jwt、session 三者的数据流
- authorize 回调:用户登录验证时触发,负责校验邮箱密码,从 MongoDB 查询用户数据。验证通过后返回的用户对象,会作为
user参数传入 jwt 回调。 - jwt 回调:首次登录时拿到 authorize 返回的 user 对象,把需要的额外字段(比如 MongoDB 的
_id)存入 token;后续每次请求时,会传入已有的 token,按需更新后返回即可。这个 token 会被加密存储,作为会话的核心凭证。 - session 回调:每次调用
useSession()或getServerSession()时触发,接收 jwt 回调生成的 token,把 token 里的自定义字段注入到 session 对象中,最终返回给调用方,这样你就能在会话中拿到 MongoDB 的用户 ID 等额外属性了。
具体代码修改逻辑
- 先修复 authorize 回调里的小问题:原代码中
if (!customer) null缺少return,会导致后续代码报错,要改成return null。 - jwt 回调:当首次登录(user 参数存在)时,把用户的
_id、name、email合并到 token 中返回;后续请求直接返回 token 即可。 - session 回调:把 token 里的自定义字段赋值给
session.user,返回更新后的 session。
完整的 authOptions 代码
export const authOptions = { providers: [ CredentialsProvider({ name: 'Sign in', credentials: {}, async authorize(credentials, req) { const { email, password } = credentials try { await connectDB() const customer = await Customer.findOne({ email }) // 修复:添加return if (!customer) return null // 校验密码 const pwdComparisonResult = await bcrypt.compare(password, customer.password) if (pwdComparisonResult) { // 返回用户对象,会传给jwt回调的user参数 return customer } return null } catch (error) { console.log('error ', error); } } }), ], callbacks: { async jwt({ token, user }) { // 首次登录时,user存在,把用户的额外字段加入token if (user) { token.id = user._id.toString(); // 把ObjectId转成字符串,避免序列化问题 token.name = user.name; token.email = user.email; } // 后续请求直接返回token return token; }, async session({ session, token }) { // 把token里的字段注入到session.user中 if (token) { session.user.id = token.id; session.user.name = token.name; session.user.email = token.email; } // 返回最终的会话对象 return session; } }, session: { strategy: "jwt" }, pages: { signIn: '/login', } }
注意点
- MongoDB 的
_id是 ObjectId 类型,要转成字符串再存入 token,避免 JSON 序列化问题。 - 后续你需要的其他用户字段,都可以按照同样的逻辑添加到 jwt 和 session 回调中。
内容的提问来源于stack exchange,提问作者karim
相关产品推荐
相关产品推荐

