node.js - 使用 jwt 和 nodejs 的密码重置链接
问题描述
此代码不起作用
router.put('/requestpass',function(req,res){
console.log('inside password');
async.waterfall([
function(done) {
user.findOne({
email: req.query.useremail
}).exec(function(err, user) {
if (user) {
done(err, user);
} else {
done('User not found.');
}
});
},
function(user, done) {
创建令牌
var token= user.generateJwt();
done(err, user, token);
},
// 使用新的令牌和到期日期更新用户对象
function(user, token, done) {
user.findOneAndUpdate({ email : req.query.useremail }, { token: token, reset_password_expires: Date.now() + 86400000 }, { upsert: true, new: true }).exec(function(err, new_user) {
if(err){console.log('error hain')}
done(err, token, new_user);
});
},
//配置邮箱
function(token, user, done) {
ejs.renderFile(__dirname + "../templates/url.ejs", { url: 'http://localhost:3000/auth/reset_password?token=' + token }, function (err, data) {
if (err) {
console.log(err);
} else {
var mainOptions = {
from: 'kapilutkarsh1@gmail.com',
to: "kapilutkarsh1@gmail.com",
subject: 'Password Reset',
html: data
};
console.log("html data >", mainOptions.html);
transporter.sendMail(mainOptions, function (err, info) {
if (err) {
console.log(err);
} else {
console.log('Message sent: ' + info.response);
}
});
}
});
}
], function(err) {
return res.status(422).json({ message: err });
});
});
我已经制作了这个功能,它将向用户发送重置密码链接,但它不起作用,它在用户身上显示错误。findOneandupdate
然后在下面的电子邮件配置中是函数生成令牌
userSchema.methods.generateJwt = function() {
var expiry = new Date();
expiry.setDate(expiry.getDate() + 7);
return jwt.sign({
_id: this._id,
email: this.email,
name: this.name,
exp: parseInt(expiry.getTime() / 1000),
}, "MY_SECRET"); //
};
that's how I have configured email
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: '**',
pass: '****'
}
});
解决方案
Try this code
// request to send smtp email containing jwt token in the URL
router.post('/forgot', function(req, res, next){
async.waterfall([
function(done){
Usermodel.findOne({email: req.body.email}, function(err, user){
if(!user){
return res.status(422).send({errors: [{title: 'Invalid email!', detail: 'User does not exist'}]});
}
const token = jwt.sign({
userId: user.id,
username: user.username,
resetPasswordToken: user.resetPasswordToken
}, config.SECRET, { expiresIn: '1h' });
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err){
done(err, token, user);
});
});
},
function(token, user, done){
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'XXXX',
pass: 'XXXX'
}
});
const mailOptions = {
to: user.email,
from: 'xxxx@gmail.com',
subject: 'Nodejs password reset',
text: 'You are receiving this email. Please click on the email for password reset ' +
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email'
};
smtpTransport.sendMail(mailOptions, function(err){
console.log('mail sent');
done(err, 'done');
});
}
], function(err){
if(err) return next(err);
});
});
// request to get and verify if the token has expired or user is invalid
router.get('/reset/:token', function(req, res){
Usermodel.findOne({resetPasswordToken: req.params.token, resetPasswordExpires: {$gt: Date.now() } }, function(err, user){
if(!user) {
return res.status(422).send({errors: [{title: 'Invalid token!', detail: 'User does not exist'}]});
}
res.json('reset', {token: req.params.token});
});
});
// request to update the password in database if password and confirm password is matching. Also send email to user regarding successful password change
router.post('/reset/:token', function(req, res){
async.waterfall([
function(done) {
Usermodel.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user){
if(!user){`enter code here`
return res.status(422).send({errors: [{title: 'error', detail: 'Password reset token is invalid or has expired'}]});
}
if(req.body.password === req.body.confirm){
user.setPassword(req.body.password, function(err){
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
user.save(function(err){
req.logIn(user, function(err) {
done(err, user);
});
});
});
} else {
return res.status(422).send({errors: [{title: 'error', detail: 'Password do not match'}]});
}
});
},
function(user, done){
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'XXXX',
pass: 'XXXX'
}
});
var mailOptions = {
to: user.email,
from: 'xxxx@gmail.com',
subject: 'Your password has been changed',
text: 'Hello,\n\n' +
'This is a confirmation that the password for your account ' + user.email + ' has just changed'
};
smtpTransport.sendMail(mailOptions, function(err){
done(err);
});
}
], function(err){
res.redirect('/');
});
});
推荐阅读
- unity3d - 屏幕空间 - Unity 中用于 VR 的叠加画布
- javascript - 是否可以使用自定义 YAML 样式而不是 truckonlytile png 图层来设计卡车特定的路标?
- c# - 实体框架是存储库吗
- powershell - 使用 while -or 运算符导致无限循环
- google-apps-script - Sheets插件中Google Scripts Time-Based Trigger的问题总是失败
- javascript - 循环内的 HTML 元素处理 - 使用 JS
- javascript - 如何在javascript Object.defineProperty 中定义数组的getter 函数?
- count - 包括切片机的Countrows
- windows - 使用 docker 发出正在运行的项目
- android - Android 警报对话框单元测试