I'm implementing a passport reset but req.login
doesn't seem to be working.
Here is my route
// Token URL :post
router.post('/users/reset/:token', (req, res, next) => {
if(req.body.password === req.body['password-confirm']) {
req.flash('error', 'Passwords do not match!');
res.redirect('/users/forgot');
}
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: { $gt: Date.now() }
}, function(err, user) {
if(!user) {
req.flash('error', ' Password reset is invalid or has expired');
res.redirect(302, '/login');
}
const setPassword = promisify(user.setPassword, user);
setPassword(req.body.password);
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
const updatedUser = user.save();
req.login(updatedUser);
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
return res.redirect('/dashboard' + req.user);
});
});
and here is the logs
Thu Jan 25 2018 22:45:10 GMT+0000 (GMT): GET /users/reset/3eab13651335967925c180427bfb2ccc956187be
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Thu, 25 Jan 2018 22:45:10 GMT") }, resetPasswordToken: '3eab13651335967925c180427bfb2ccc956187be' }, { fields: {} })
Thu Jan 25 2018 22:45:10 GMT+0000 (GMT): GET /favicon.ico
Thu Jan 25 2018 22:45:20 GMT+0000 (GMT): POST /users/reset/3eab13651335967925c180427bfb2ccc956187be
Mongoose: users.findOne({ resetPasswordExpires: { '$gt': new Date("Thu, 25 Jan 2018 22:45:20 GMT") }, resetPasswordToken: '3eab13651335967925c180427bfb2ccc956187be' }, { fields: {} })
events.js:136
throw er; // Unhandled 'error' event
^
Error: req#login requires a callback function
at IncomingMessage.req.login.req.logIn (/Users/benbagley/Code/poetry-out-loud/node_modules/passport/lib/http/request.js:47:44)
at /Users/benbagley/Code/poetry-out-loud/routes/users.js:326:9
at model.Query.<anonymous> (/Users/benbagley/Code/poetry-out-loud/node_modules/mongoose/lib/model.js:4056:16)
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:273:21
at /Users/benbagley/Code/poetry-out-loud/node_modules/kareem/index.js:131:16
at process._tickCallback (internal/process/next_tick.js:150:11)
[nodemon] app crashed - waiting for file changes before starting...
In mongoose Model.save()
is asynchronous (because it takes time to get to the DB and back). When you do the following...
const updatedUser = user.save();
req.login(updatedUser);
you are not passing the updatedUser to req.login
- you are passing an unresolved Promise. This is why the login function fails. req.login
is also asynchronous!
You need to wait for the functions to finish before using their results. You can to this in three ways:
1) A callback function - this is what you have passed as the second argument to User.findOne
.
user.save((saveError, updatedUser) => {
// Check if saveError is present here and handle appropriately
req.login(updatedUser, loginError => {
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
res.redirect('/dashboard' + req.user);
})
});
2) Calling .then
on the returned promise, and passing a function to then
which will be executed when the promise resolves
user.save()
.then(updatedUser => req.login(updatedUser))
.then(() => {
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
res.redirect('/dashboard' + req.user);
})
.catch(err => /* handle error */);
3) Using async/await and awaiting the resolution of the promise. The whole function needs to be marked as async, then we can await
any functions that return promises:
router.post('/users/reset/:token', async (req, res, next) => {
try {
if(req.body.password === req.body['password-confirm']) {
req.flash('error', 'Passwords do not match!');
res.redirect('/users/forgot');
}
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');
res.redirect(302, '/login');
}
const setPassword = promisify(user.setPassword, user);
await setPassword(req.body.password);
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
const updatedUser = await user.save();
await req.login(updatedUser);
req.flash('success_msg', 'Your password has been reset successfully! You are now logged in!');
return res.redirect('/dashboard' + req.user);
} catch (err) {
// handle error
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.