0

我正在使用一个保存联系人的程序。我想添加一个新功能,让您可以通过电子邮件帐户向联系人发送电子邮件。我尝试使用 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');
            }
        });


    };


});

我的问题是:

如何修复错误?

我可以用不同的方式做到这一点,这样更容易更好吗?

4

1 回答 1

2

我是否正确理解您希望您的用户输入他们的私人/外部电子邮件提供商的凭据,以便您可以使用该提供商发送电子邮件?

在这种情况下,您的问题没有通用答案,因为所需配置的细节高度取决于电子邮件提供商。例如在您的代码中:

    var parts = email.substring(email.lastIndexOf('@')+ 1);
    const hosts = 'smtp.' + parts;
    var transporter = nodemailer.createTransport({
        host: hosts,
        port: 587,
        auth: {
            user: email,
            pass: password
        }
    });

这个块已经有一些硬编码的假设,即 smtp 主机john.doe@example.netsmtp.example.org,并且该电子邮件的用户名john.doe@example.net也是- 两者 - 对于许多电子邮件提供商来说不一定是这种情况。

因此,即使这对您有用,也很可能不适用于您的所有用户

相反,您应该使用您的应用程序可以将电子邮件转发到的单个 smtp 网关/中继。然后,您也不需要用户自己的凭据,但可以将您的应用程序的登录凭据用于该 smtp 网关。

但这取决于您的 smtp 网关的配置是否允许您使用任意发件人地址进行发送。即使您的网关可能允许这样做,邮件也可能由于垃圾邮件过滤器而被阻止,因为您的网关可能不允许为用户的域发送电子邮件,请参阅SPF

因此,我建议您 - 除了使用专用的 smtp 网关之外 - 使用您拥有和控制的电子邮件地址/域进行发送。您仍然可以增加直接来自用户的邮件,例如通过适当地设置显示名称和回复标题

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"

对于这封邮件,收件人会将发送用户的姓名显示为发件人(但您的应用程序的电子邮件而不是用户的电子邮件),并且当点击回复按钮时,默认情况下回复将被发送回 - 取决于电子邮件客户端 -用户,即在这种情况下john.doe@example.org

于 2019-09-14T14:27:20.537 回答