PassportJS本地认证问题:deserializeUser未调用且req.user为undefined
PassportJS本地认证:deserializeUser未调用且req.user为undefined的解决方法
你的问题核心是中间件顺序错误,其次是deserializeUser中返回的数据格式存在问题,以下是具体修正方案:
1. 修正中间件加载顺序
Passport和Session的中间件有严格的加载顺序要求,错误的顺序会导致Passport无法正确读取Session中的用户标识,进而不会触发deserializeUser。
正确的中间件加载顺序必须遵循:
- 解析请求体的中间件(express.json/urlencoded)
- CORS配置
- Cookie解析中间件(cookieParser)
- Session中间件
- Passport初始化(passport.initialize())
- Passport Session处理(passport.session())
- Passport配置(config(passport))
修正后的index.js代码:
app.use(express.json()); // 解析JSON请求体 app.use(express.urlencoded({ extended: true })); // 解析表单请求体 app.use( cors({ origin: "http://localhost:3000", // React应用地址 credentials: true, }) ); // 先加载cookieParser,解析Session依赖的Cookie app.use(cookieParser("secretcode")); app.use( session({ secret: "secretcode", resave: false, saveUninitialized: false, }) ); // 先初始化Passport,再处理Session关联 app.use(passport.initialize()); app.use(passport.session()); config(passport); app.post("/login", passport.authenticate('local', { failureRedirect: '/login', failureMessage: true }), function(req, res) { res.redirect('/~' + req.user.username); }); app.get("/user", (req, res) => { res.send(req.user); });
2. 修正deserializeUser的返回值
你的config.js中,db.query查询用户后返回的user是结果数组(即使只有一条匹配数据),但Passport期望接收单个用户对象,需要取数组的第一个元素返回:
修正后的deserializeUser代码片段:
passport.deserializeUser(function(id, cb) { db.query('SELECT * FROM users WHERE id = ?', [ id ], function(err, user) { if (err) { return cb(err); } // 取数组第一个元素作为用户对象返回 return cb(null, user[0]); }); });
3. 额外验证点
- 确认客户端请求时携带凭证:使用axios需设置
withCredentials: true,使用fetch需设置credentials: 'include' - 检查Session配置的
secret与cookieParser的密钥是否一致(你的代码中均为"secretcode",此部分无问题) - 登录成功后可打印
req.session.passport.user,确认Session已正确写入用户ID
内容的提问来源于stack exchange,提问作者Tryer outer
相关产品推荐
相关产品推荐

