我正在使用一个保存联系人的程序。我想添加一个新功能,使您可以通过电子邮件帐户向联系人发送电子邮件。 我尝试使用nodemailer进行此操作,从用户需要填写的表单中获取登录数据。
但是nodemailer给我发送了一个错误,看起来是这样:
Error: Invalid login: 535-5.7.8 Username and Password not accepted.
我尝试使用应用密码并激活了不太安全的选项,但是错误仍然存在。看我的代码:
我在这里获取用户的电子邮件和密码:
router.post('/email', isLoggedIn, async (req, res) => {
var { email } = req.body;
var { password } = req.body;
var parts = email.substring(email.lastIndexOf('@')+ 1);
exports.email = email;
exports.password = password;
res.redirect('/links/message')
});
我在这里留言:
router.post('/sendmessage', isLoggedIn, async (req, res) => {
const { message } = req.body;
const { assumpt } = req.body;
exports.message = message;
exports.assumpt = assumpt;
res.redirect('/links/contactsemail')
});
最后,我选择了您需要发送电子邮件的类别联系人,并发送了电子邮件以及用户给我的消息和数据登录信息:
router.post('/contactsend', isLoggedIn, async (req, ress) => {
const { contacts } = req.body;
const row = await pool.query('SELECT count(email) AS email FROM links WHERE user_id=? AND category=? AND email IS NOT NULL',[req.user.id, contacts]);
const rows = row[0].email;
const assumpt = myModule.assumpt;
const message = myModule.message;
const email = myModule.email;
const password = myModule.password
var parts = email.substring(email.lastIndexOf('@')+ 1);
const hosts = 'smtp.' + parts;
var transporter = nodemailer.createTransport({
host: hosts,
port: 587,
auth: {
user: email,
pass: password
}
});
for (i = 1; i <= rows; i++ ){
var email1 = await pool.query('SELECT email AS email FROM (SELECT email, ROW_NUMBER() OVER (ORDER BY email) AS rn FROM links WHERE user_id= ? AND category=?) q WHERE rn = ?', [req.user.id, contacts, i]);
var email1 = email1[0].email;
var mailOptions = {
from: email,
to: email1,
subject: assumpt,
text: message
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
res.flash('success', 'Missatge enviat correctament');
res.redirect('/links');
}
});
};
});
我的问题是:
如何解决该错误?
我可以通过不同的方式来做到这一点,因为它更容易,更好?
答案 0 :(得分:0)
我是否正确理解您希望用户输入其私人/外部电子邮件提供商的凭据,以便您可以使用该提供商发送电子邮件?
在这种情况下,您的问题没有通用的答案,因为所需配置的细节在很大程度上取决于电子邮件提供商。例如,在您的代码中:
var parts = email.substring(email.lastIndexOf('@')+ 1);
const hosts = 'smtp.' + parts;
var transporter = nodemailer.createTransport({
host: hosts,
port: 587,
auth: {
user: email,
pass: password
}
});
此块已经有一些硬编码的假设,即john.doe@example.net
的smtp主机为smtp.example.org
,该电子邮件的用户名也为{{ 1}},这两者-不一定对许多电子邮件提供商都是如此。
所以即使这对您来说 也很有可能对所有用户 无效!
相反,您应该使用一个smtp网关/您的应用程序可以将电子邮件转发到的中继。然后,您也将不需要用户自己的凭据,但可以将您的应用程序的登录凭据用于该smtp网关。
但是是否允许您使用任意发件人地址发送邮件,这取决于您的smtp网关的配置。而且即使您的网关可能允许这样做,由于不允许您的网关发送用户域的电子邮件,由于垃圾邮件过滤器,邮件也可能被阻止,请参阅SPF。
因此,除使用专用的smtp网关外,我建议您使用自己拥有和控制的电子邮件地址/域进行发送。您仍然可以增加直接来自用户的邮件,例如通过适当设置显示名称和Reply-To header:
john.doe@example.net
对于此邮件,收件人将获得显示为发件人的发送用户的姓名(但您应用的电子邮件而非该用户的姓名),并且在单击“答复”按钮时,默认情况下将答复(取决于电子邮件客户端)发送回用户,例如From: "John Doe" <myapp@example.com>
To: jane.doe@example.org
Reply-To: "John Doe" <john.doe@example.org>
Subject: "A message from John Doe via MyApp"
。