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

如何在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 等额外属性了。

具体代码修改逻辑

  1. 先修复 authorize 回调里的小问题:原代码中 if (!customer) null 缺少 return,会导致后续代码报错,要改成 return null。
  2. jwt 回调:当首次登录(user 参数存在)时,把用户的 _id、name、email 合并到 token 中返回;后续请求直接返回 token 即可。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:32:52