使用passport-local-mongoose修改密码后自动登录失败问题排查
Got it, let's fix this error you're running into. The core issue here is that Passport's req.login() (or req.logIn()) method is callback-based, not promise-based—so you can't directly use await on it like you're doing now. That's exactly why you're seeing the "req#login requires a callback function" message.
两种可行的解决方案:
方案1:将req.login包装成Promise(适配async/await语法)
Wrap the callback-based req.login in a Promise so you can use await consistently with the rest of your async code:
exports.update = async (req, res) => { try { const user = await User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: {$gt: Date.now()} }); if(!user){ req.flash('error', 'Password reset is invalid or has expired'); return res.redirect('/login'); } await user.setPassword(req.body.password); user.resetPasswordToken = undefined; user.resetPasswordExpires = undefined; const updatedUser = await user.save(); // 把req.login包装成Promise来支持await await new Promise((resolve, reject) => { req.login(updatedUser, (err) => { if (err) return reject(err); resolve(); }); }); req.flash('success', "Nice! your password has been reset! You are now logged in!"); res.redirect('/'); } catch (err) { // 捕获所有可能的错误并反馈给用户 req.flash('error', 'An error occurred while completing your password reset'); res.redirect('/login'); } };
方案2:直接使用回调式写法
If you prefer to stick with the original callback pattern for this step, you can rewrite that part like this:
exports.update = async (req, res) => { try { const user = await User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: {$gt: Date.now()} }); if(!user){ req.flash('error', 'Password reset is invalid or has expired'); return res.redirect('/login'); } await user.setPassword(req.body.password); user.resetPasswordToken = undefined; user.resetPasswordExpires = undefined; const updatedUser = await user.save(); // 使用Passport原生的回调式login方法 req.login(updatedUser, (err) => { if (err) { req.flash('error', 'Failed to log you in after password reset'); return res.redirect('/login'); } req.flash('success', "Nice! your password has been reset! You are now logged in!"); res.redirect('/'); }); } catch (err) { req.flash('error', 'An error occurred during password reset'); res.redirect('/login'); } };
额外小修正:
I noticed a typo in your original code: req.flash('sucess') should be req.flash('success')—I fixed that in both examples above so your flash message works correctly.
内容的提问来源于stack exchange,提问作者Shantanu Kumar

