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存储会在热重载、实例销毁时丢失数据,必须配置持久化存储:
- 安装依赖:
npm install connect-mongo - 修改
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
相关产品推荐
相关产品推荐

