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

Next.js搭配passport-and-next-connect与Mongoose时req.user为undefined问题咨询

问题根因与配置方案

req.user为undefined核心是passport序列化/反序列化逻辑异常、session存储配置错误两类原因,按以下步骤修改即可解决:

步骤1:修正passport核心配置

你替换Mongoose逻辑后大概率没有调整lib/passport.js中的序列化、反序列化规则,这是最常见的问题点,参考配置如下:

import passport from 'passport'
import LocalStrategy from 'passport-local'
import User from '../models/User' // 替换为你自己的Mongoose用户模型

// 序列化:登录成功后将用户id存入session
passport.serializeUser((user, done) => {
  done(null, user._id.toString())
})

// 反序列化:每次请求从session读取id,查询完整用户信息挂载到req.user
passport.deserializeUser(async (id, done) => {
  try {
    // 查库时排除密码等敏感字段
    const user = await User.findById(id).select('-password')
    done(null, user)
  } catch (err) {
    done(err)
  }
})

// 你的登录验证策略,以下为本地账号密码示例
passport.use(new LocalStrategy(async (username, password, done) => {
  try {
    const user = await User.findOne({ username })
    if (!user) return done(null, false, { message: '账号不存在' })
    // 替换为你自己的密码验证逻辑,比如bcrypt对比
    const passwordValid = await user.comparePassword(password)
    if (!passwordValid) return done(null, false, { message: '密码错误' })
    done(null, user)
  } catch (err) {
    done(err)
  }
}))

export default passport

步骤2:清理auth.js冗余模拟代码

删除你当前middleware/auth.js中遗留的示例模拟数据库逻辑,避免干扰真实session写入:

// 删掉这段代码
.use((req, res, next) => {
 // Initialize mocked database
 // Remove this after you add your own database
    req.session.users = req.session.users || []
    next()
  })

步骤3:配置持久化session存储

Next.js API路由是无服务运行模式,默认的内存session存储会在热重载、实例销毁时丢失数据,必须配置持久化存储:

  1. 安装依赖:npm install connect-mongo
  2. 修改lib/session.js配置:
import session from 'express-session'
import MongoStore from 'connect-mongo'

export default function sessionConfig() {
  return session({
    name: 'sess',
    secret: process.env.TOKEN_SECRET,
    resave: false,
    saveUninitialized: false,
    // 用MongoDB存储session
    store: MongoStore.create({
      mongoUrl: process.env.MONGODB_URI, // 替换为你的MongoDB连接地址
      collectionName: 'sessions'
    }),
    cookie: {
      maxAge: 60 * 60 * 8, // 8小时
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      path: '/',
      sameSite: 'lax',
    },
  })
}

步骤4:确认登录接口调用req.login

passport要求登录验证通过后必须手动调用req.login将用户信息写入session,你的登录接口(比如api/login)需要包含以下逻辑:

import nextConnect from 'next-connect'
import auth from '../../middleware/auth'
import passport from '../../lib/passport'

const handler = nextConnect()
handler.use(auth).post(passport.authenticate('local'), (req, res) => {
  // 手动触发session写入
  req.login(req.user, (err) => {
    if (err) return res.status(500).json({ error: '登录失败' })
    res.json({ user: { _id: req.user._id } })
  })
})

export default handler

所有配置修改完成后重启开发服务,先调用登录接口完成身份验证,再访问/api/user即可正常获取req.user。

内容的提问来源于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.28 12:45:03