Passport.js+Express-MySQL用户认证序列化失败问题求助
解决Passport.js的"Failed to serialize user into session"错误
嘿,我一眼就发现你代码里的核心问题了——在LocalStrategy的验证逻辑里,你没有把用户对象传给Passport的done回调,而是传了个布尔值true,这直接导致serializeUser函数拿不到user.id,自然就序列化失败了。
具体问题分析
看你这段LocalStrategy的代码:
passport.use(new LocalStrategy( function(username, password, done) { connection.query('SELECT password, salt FROM users WHERE email = ?', [username], function(err, results, fields){ //DB error if(err) {done(err)}; //no user was found if(results.length === 0) { done(null, false); } var salt = results[0].salt; if(bcrypt.hashSync(password, salt) === results[0].password) { //Success return done(null, true); // 这里是核心错误! } else { //Wrong password return done(null, false); } }); } ));
这里存在两个关键问题:
- 你只查询了
password和salt字段,没有获取包含id在内的完整用户信息; - 验证成功时返回
done(null, true),但Passport需要你传递完整的用户对象,这样后续的serializeUser才能从对象里读取user.id完成序列化。
修正步骤
修改查询语句,获取完整用户数据
把查询语句从SELECT password, salt FROM users WHERE email = ?改成SELECT * FROM users WHERE email = ?,这样就能拿到包含id在内的所有用户信息。验证成功时传递用户对象
把return done(null, true);改成return done(null, results[0]);,把查询到的用户对象完整传给Passport。
修正后的LocalStrategy代码如下:
passport.use(new LocalStrategy( function(username, password, done) { // 查询完整的用户信息 connection.query('SELECT * FROM users WHERE email = ?', [username], function(err, results, fields){ if(err) { return done(err); // 加上return避免后续代码执行 } if(results.length === 0) { return done(null, false); } var user = results[0]; // 验证密码 if(bcrypt.hashSync(password, user.salt) === user.password) { // 传递用户对象给done return done(null, user); } else { return done(null, false); } }); } ));
额外小优化
你原来的代码里if(err) {done(err)};没有加return,可能会导致后续代码继续执行引发不必要的错误,建议统一加上return语句。
这样修改后,serializeUser就能正确拿到user.id存入会话,deserializeUser也能根据id查询到用户,会话异常的问题也就解决了。
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

