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

Next.js+Mongoose+Passport.js环境下req.user为undefined问题求助

问题排查与修复方案


  1. Passport自定义回调未手动完成登录流程
    Passport的passport.authenticate自定义回调不会自动将用户挂载到req对象,也不会自动触发会话写入,校验通过的用户存储在回调的user参数中,你需要显式调用req.logIn完成登录流程:
passport.authenticate('local', (err, user, info) => {
  if (err) return next(err)
  if (!user) return res.status(401).json({ error: info.message })
  // 手动触发登录,完成用户挂载和会话初始化
  req.logIn(user, (err) => {
    if (err) return next(err)
    // 此时req.user才会被正确赋值
    req.session.user = req.user
    // 补充后续返回响应的逻辑即可
    return res.json({ user: { _id: user._id } })
  })
})(req, res, next)

注意:自定义回调模式下,需要手动把req, res, next传给authenticate返回的函数,否则校验逻辑不会执行。

  1. 数据库连接中间件异步逻辑未等待
    你新增的数据库连接中间件如果connectDB是异步方法,直接调用后马上执行next会导致后续逻辑执行时数据库还未连接完成,需要修改为异步中间件:
.use(async (req, res, next) => {
  await connectDB()
  next()
})

如果已经在login接口里单独写了await connectDB(),可以不用重复在全局auth中间件中添加,避免重复建立连接。

  1. Passport序列化/反序列化逻辑校验
    确认你的../lib/passport文件中已经正确实现了passport.serializeUser和passport.deserializeUser方法,这两个方法是Passport实现会话持久化的必要逻辑,参考示例:
// 序列化:把用户ID存入会话
passport.serializeUser((user, done) => {
  done(null, user._id)
})

// 反序列化:请求时从会话取ID查询完整用户信息挂载到req.user
passport.deserializeUser(async (id, done) => {
  const user = await UserModel.findById(id)
  done(null, user)
})
  1. 会话配置校验
    确认你的环境变量中TOKEN_SECRET已正确配置,缺失该值会导致session加密失败,数据无法写入存储。开发环境下可以直接打印req.session确认会话本身是正常生成的。

内容的提问来源于stack exchange,提问作者Antonio Pavicevac-Ortiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:15:05