使用Nodemailer发送Gmail重置密码邮件遇TypeError错误求助
解决Nodemailer结合Gmail发送重置密码邮件的"TypeError: Cannot create property 'mailer' on string 'smtpTransport'"错误
我来帮你排查这个问题,这个错误其实是Nodemailer API调用方式不符合当前版本规范导致的,咱们一步步解决:
错误原因
你调用nodemailer.createTransport('SMTP', {...})的方式是旧版Nodemailer的写法,在新版Nodemailer中,createTransport方法不需要第一个字符串参数'SMTP',直接传递配置对象即可。旧写法会让Nodemailer错误地把字符串'SMTP'当作 transporter 的实例基础,进而尝试在这个字符串上创建mailer属性,最终抛出类型错误。
修正方案
1. 修正createTransport的调用方式
把原来的这部分代码:
var smtpTransport = nodemailer.createTransport('SMTP', { service: 'gmail', auth: { user: 'abc@gmail.com', pass: '123456' } });
替换成新版的写法:
var smtpTransport = nodemailer.createTransport({ service: 'gmail', auth: { user: 'abc@gmail.com', pass: '你的应用专用密码' // 重要:这里需要注意Gmail的认证规则 } });
2. 处理Gmail的认证限制
现在Gmail对第三方应用的登录有严格限制:
- 如果你的账号开启了两步验证(2FA):必须使用Google账号生成的应用专用密码代替普通密码,不要直接填你的登录密码。
- 如果未开启2FA:需要在Google账号设置中开启"不太安全的应用访问"(不过Google已经逐步移除这个选项,更推荐启用2FA并使用应用密码)。
3. 确保使用最新版Nodemailer
如果你的Nodemailer版本过旧,也可能出现API不兼容的问题,执行以下命令更新到最新稳定版:
npm install nodemailer@latest
完整修正后的代码片段
这里是修改后的/forgot接口完整代码,你可以直接替换对应的部分:
var nodemailer = require('nodemailer'); app.post('/forgot', function(req, res, next) { async.waterfall([ function(done) { crypto.randomBytes(20, function(err, buf) { var token = buf.toString('hex'); done(err, token); }); }, function(token, done) { User.findOne({ email: req.body.email }, function(err, user) { if (!user) { req.flash('error', 'No account with that email address exists.'); return res.redirect('/forgot'); } user.resetPasswordToken = token; user.resetPasswordExpires = Date.now() + 3600000; // 1 hour user.save(function(err) { done(err, token, user); }); }); }, function(token, user, done) { console.log(token, "Token"); console.log(user, "user") // 修正后的createTransport调用 var smtpTransport = nodemailer.createTransport({ service: 'gmail', auth: { user: 'abc@gmail.com', pass: '你的应用专用密码' } }); var mailOptions = { to: user.email, from: 'myproducts@mailinator.com', subject: 'My Products Password Reset', text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' + 'Please click on the following link, or paste this into your browser to complete the process:\n\n' + 'http://' + req.headers.host + '/reset/' + token + '\n\n' + 'If you did not request this, please ignore this email and your password will remain unchanged.\n' }; smtpTransport.sendMail(mailOptions, function(err) { req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.'); done(err, 'done'); }); } ], function(err) { if (err) return next(err); res.redirect('/forgot'); }); });
按照以上步骤修改后,应该就能解决这个类型错误,成功发送重置密码邮件了。
内容的提问来源于stack exchange,提问作者Aditya Rajak
相关产品推荐
相关产品推荐

