繁体   English   中英

带有 Gmail 和 NodeJS 的 Nodemailer

[英]Nodemailer with Gmail and NodeJS

我尝试使用 nodemailer 来实现使用 NodeJS 的联系表单,但它只适用于本地,它不适用于远程服务器......

我的错误信息:

[website.fr-11 (out) 2013-11-09T15:40:26] { [AuthError: Invalid login - 534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787
[website.fr-11 (out) 2013-11-09T15:40:26] 534 5.7.14 54 fr4sm15630311wib.0 - gsmtp]
[website.fr-11 (out) 2013-11-09T15:40:26]   name: 'AuthError',
[website.fr-11 (out) 2013-11-09T15:40:26]   data: '534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX\r\n534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC\r\n534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX\r\n534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r\r\n534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.\r\n534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787\r\n534 5.7.14 54 fr4sm15630311wib.0 - gsmtp',
[website.fr-11 (out) 2013-11-09T15:40:26]   stage: 'auth' }

我的 controller:

exports.contact = function(req, res){
    var name = req.body.name;
    var from = req.body.from;
    var message = req.body.message;
    var to = '*******@gmail.com';
    var smtpTransport = nodemailer.createTransport("SMTP",{
        service: "Gmail",
        auth: {
            user: "******@gmail.com",
            pass: "*****"
        }
    });
    var mailOptions = {
        from: from,
        to: to, 
        subject: name+' | new message !',
        text: message
    }
    smtpTransport.sendMail(mailOptions, function(error, response){
        if(error){
            console.log(error);
        }else{
            res.redirect('/');
        }
    });
}

我通过访问以下网址解决了这个问题(同时使用我要发送邮件的帐户连接到谷歌):

https://www.google.com/settings/security/lesssecureapps

在那里我启用了不太安全的应用程序。

完毕

请参阅 nodemailer 的连接 Gmail 的官方指南:

https://community.nodemailer.com/using-gmail/

-

这样做后它对我有用:

  1. 启用不太安全的应用程序 - https://www.google.com/settings/security/lesssecureapps
  2. 暂时禁用验证码,以便您可以连接新设备/服务器 - https://accounts.google.com/b/0/displayunlockcaptcha

简单的解决方案:

var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');

var transporter = nodemailer.createTransport(smtpTransport({
  service: 'gmail',
  host: 'smtp.gmail.com',
  auth: {
    user: 'somerealemail@gmail.com',
    pass: 'realpasswordforaboveaccount'
  }
}));

var mailOptions = {
  from: 'somerealemail@gmail.com',
  to: 'friendsgmailacc@gmail.com',
  subject: 'Sending Email using Node.js[nodemailer]',
  text: 'That was easy!'
};

transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(error);
  } else {
    console.log('Email sent: ' + info.response);
  }
});  

步骤1:

去这里https://myaccount.google.com/lesssecureapps并启用不太安全的应用程序。 如果这不起作用,那么

第2步

去这里https://accounts.google.com/DisplayUnlockCaptcha并启用/继续,然后尝试。

对我来说,单独的第 1 步不起作用,所以我不得不进行第 2 步。

我还尝试删除 nodemailer-smtp-transport 包,令我惊讶的是它可以工作。 但是当我重新启动系统时,它给了我同样的错误,所以我不得不去打开不太安全的应用程序(我在工作后禁用了它)。

然后为了好玩,我只是尝试关闭(不太安全的应用程序)和vola它再次工作!

您应该使用XOAuth2 令牌连接到 Gmail。 不用担心,Nodemailer 已经知道这一点:

var smtpTransport = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
      XOAuth2: {
        user: smtpConfig.user,
        clientId: smtpConfig.client_id,
        clientSecret: smtpConfig.client_secret,
        refreshToken: smtpConfig.refresh_token,
        accessToken: smtpConfig.access_token,
        timeout: smtpConfig.access_timeout - Date.now()
      }
    }
  };

您需要前往Google Cloud Console注册您的应用。 然后,您需要检索您希望使用的帐户的访问令牌。 您可以为此使用passportjs

这是它在我的代码中的样子:

var passport = require('passport'),
    GoogleStrategy = require('./google_oauth2'),
    config = require('../config');

passport.use('google-imap', new GoogleStrategy({
  clientID: config('google.api.client_id'),
  clientSecret: config('google.api.client_secret')
}, function (accessToken, refreshToken, profile, done) {
  console.log(accessToken, refreshToken, profile);
  done(null, {
    access_token: accessToken,
    refresh_token: refreshToken,
    profile: profile
  });
}));

exports.mount = function (app) {
  app.get('/add-imap/:address?', function (req, res, next) {
    passport.authorize('google-imap', {
        scope: [
          'https://mail.google.com/',
          'https://www.googleapis.com/auth/userinfo.email'
        ],
        callbackURL: config('web.vhost') + '/add-imap',
        accessType: 'offline',
        approvalPrompt: 'force',
        loginHint: req.params.address
      })(req, res, function () {
        res.send(req.user);
      });
  });
};

工作正常:

1-安装nodemailer ,如果未安装则打包(输入cmd): npm install nodemailer

2- 转到https://myaccount.google.com/lesssecureapps并打开允许不太安全的应用程序

3-编写代码:

var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: 'trueUsername@gmail.com',
        pass: 'truePassword'
    }
});

const mailOptions = {
    from: 'any@any.com', // sender address
    to: 'true@true.com', // list of receivers
    subject: 'test mail', // Subject line
    html: '<h1>this is a test mail.</h1>'// plain text body
};

transporter.sendMail(mailOptions, function (err, info) {
    if(err)
        console.log(err)
    else
        console.log(info);
})

4-享受!

我有同样的问题。 在我的 Google 安全设置中允许“安全性较低的应用程序”使其工作!

同样的问题也发生在我身上。 我在 localhost 上测试了我的系统,然后部署到服务器(位于不同的国家),然后当我在生产服务器上尝试系统时,我看到了这个错误。 我尝试了这些来修复它:

  1. https://www.google.com/settings/security/lesssecureapps启用它,但它不是我的解决方案
  2. https://g.co/allowaccess我允许在有限的时间内从外部访问,这解决了我的问题。

上述解决方案都不适合我。 我使用了NodeMailer 文档中存在的代码。 它看起来像这样:

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        type: 'OAuth2',
        user: 'user@example.com',
        serviceClient: '113600000000000000000',
        privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
        expires: 1484314697598
    }
}); 

我发现Greg T 的回答中提到的这篇文章中描述的最简单的方法是创建一个应用程序密码,该密码在为帐户打开 2FA 后可用。

myaccount.google.com > 登录和安全 > 登录 Google > 应用密码

这为您提供了该帐户的备用密码,然后您只需将 nodemailer 配置为普通的 SMTP 服务。

var smtpTransport = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 587,
    auth: {
        user: "username@gmail.com",
        pass: "app password"
    }
});

虽然 Google 推荐 Oauth2 作为最佳选择,但此方法很简单,并且尚未在此问题中提及。

额外提示:我还发现您可以将您的应用程序名称添加到“发件人”地址,并且 GMail 不会像您尝试使用其他地址那样仅将其替换为帐户电子邮件。 IE。

from: 'My Pro App Name <username@gmail.com>'

尝试在您的 gmail 帐户中禁用验证码; 可能是根据请求者的 IP 地址触发的。 请参阅: 如何将 GMail 用作免费 SMTP 服务器并克服验证码

对我来说,使用端口和安全性以这种方式工作(我在没有安全设置的情况下使用 PHP 从 gmail 发送电子邮件时遇到问题)

我希望能帮助某人。

var sendEmail = function(somedata){
  var smtpConfig = {
    host: 'smtp.gmail.com',
    port: 465,
    secure: true, // use SSL, 
                  // you can try with TLS, but port is then 587
    auth: {
      user: '***@gmail.com', // Your email id
      pass: '****' // Your password
    }
  };

  var transporter = nodemailer.createTransport(smtpConfig);
  // replace hardcoded options with data passed (somedata)
  var mailOptions = {
    from: 'xxxx@gmail.com', // sender address
    to: 'yyyy@gmail.com', // list of receivers
    subject: 'Test email', // Subject line
    text: 'this is some text', //, // plaintext body
    html: '<b>Hello world ✔</b>' // You can choose to send an HTML body instead
  }

  transporter.sendMail(mailOptions, function(error, info){
    if(error){
      return false;
    }else{
      console.log('Message sent: ' + info.response);
      return true;
    };
  });
}

exports.contact = function(req, res){
   // call sendEmail function and do something with it
   sendEmail(somedata);
}

此处列出了所有配置(包括示例)

它是使用 createTransport 中nodemailer-smtp-transport模块解决的。

var smtpTransport = require('nodemailer-smtp-transport');

var transport = nodemailer.createTransport(smtpTransport({
    service: 'gmail',
    auth: {
        user: '*******@gmail.com',
        pass: '*****password'
    }
}));

许多答案建议允许安全性较低的应用程序,老实说这不是一个干净的解决方案。

相反,您应该生成一个专用于此用途的应用程序密码

  1. 登录您的 Google 帐户
  2. 安检
  3. 登录 Google下启用两步验证
  4. Signing in to Google下,点击App passwords
  5. 您现在将生成一个新密码。 选择应用程序作为邮件和设备作为其他(自定义名称)并命名。
  6. 保存应用密码

您现在可以使用此应用程序密码代替您的登录密码。

如果你使用 Express, express-mailer很好地包装nodemailer并且非常易于使用:

//# config/mailer.js    
module.exports = function(app) {
  if (!app.mailer) {
    var mailer = require('express-mailer');
    console.log('[MAIL] Mailer using user ' + app.config.mail.auth.user);
    return mailer.extend(app, {
      from: app.config.mail.auth.user,
      host: 'smtp.gmail.com',
      secureConnection: true,
      port: 465,
      transportMethod: 'SMTP',
      auth: {
        user: app.config.mail.auth.user,
        pass: app.config.mail.auth.pass
      }
    });
  }
};

//# some.js
require('./config/mailer.js)(app);
app.mailer.send("path/to/express/views/some_view", {
  to: ctx.email,
  subject: ctx.subject,
  context: ctx
}, function(err) {
  if (err) {
    console.error("[MAIL] Email failed", err);
    return;
  }
  console.log("[MAIL] Email sent");
});

//#some_view.ejs
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title><%= subject %></title>
  </head>
  <body>
  ... 
  </body>
</html>

出于某种原因,即使是验证码,只允许不太安全的应用程序配置对我也不起作用。 我不得不做另一个步骤,即启用 IMAP 配置:

从谷歌的帮助页面: https ://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

  • 在右上角,单击设置设置。
  • 单击设置。
  • 单击转发和 POP/IMAP 选项卡。
  • 在“IMAP 访问”部分中,选择启用 IMAP。
  • 单击保存更改。

您所有的代码都可以,只剩下剩下的就是转到链接https://myaccount.google.com/security

并继续向下滚动,你会发现允许不太安全的应用程序:打开并保持打开,你会发现没有错误。

只需添加“主机”就可以了。

host: 'smtp.gmail.com'

然后通过单击下面的链接启用“lesssecureapps”

https://myaccount.google.com/lesssecureapps

exports.mailSend = (res, fileName, object1, object2, to, subject,   callback)=> {
var smtpTransport = nodemailer.createTransport('SMTP',{ //smtpTransport
host: 'hostname,
port: 1234,
secureConnection: false,
//   tls: {
//     ciphers:'SSLv3'
// },
auth: {
  user: 'username',
  pass: 'password'
}

});
res.render(fileName, {
info1: object1,
info2: object2
}, function (err, HTML) {

smtpTransport.sendMail({
  from: "mail@from.com",
  to: to,
  subject: subject,
  html: HTML
}
  , function (err, responseStatus) {
      if(responseStatus)
    console.log("checking dta", responseStatus.message);
    callback(err, responseStatus)
  });
});
}

您必须在代码中添加 secureConnection 类型。

我使用的是旧版本的 nodemailer 0.4.1 并且遇到了这个问题。 我更新到 0.5.15,现在一切正常。

编辑 package.json 以反映更改

npm install

只需参加这些: 1-在您重新启动客户端浏览器之前不接受允许低级别电子邮件的 Gmail 身份验证 2-如果您想使用 nodemailer 发送电子邮件并且您不想使用 xouath2 协议,您应该写为 secureconnection:false 如下所示

const routes = require('express').Router();
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');



routes.get('/test', (req, res) => {
  res.status(200).json({ message: 'test!' });
});

routes.post('/Email', (req, res) =>{

    var smtpTransport = nodemailer.createTransport({
        host: "smtp.gmail.com",
        secureConnection: false,
        port: 587,
        requiresAuth: true,
        domains: ["gmail.com", "googlemail.com"],
        auth: {
            user: "your gmail account", 
            pass: "your password*"
        }
});  

  var mailOptions = {
      from: 'from@gmail.com',
      to:'to@gmail.com',
      subject: req.body.subject,
      //text: req.body.content,
      html: '<p>'+req.body.content+' </p>'
  };

  smtpTransport.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log('Error while sending mail: ' + error);
    } else {
        console.log('Message sent: %s', info.messageId);
    }
    smtpTransport.close();
});  

})

module.exports = routes;

首先安装nodemailer

npm install nodemailer  --save

导入到js文件

const nodemailer = require("nodemailer");

const smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "example@gmail.com",
        pass: "password"
    },
    tls: {
        rejectUnauthorized: false
    }
});






 const mailOptions = {
        from: "example@gmail.com",
        to: sending@gmail.com,
        subject: "Welcome to ",
        text: 'hai send from me'.
    };


    smtpTransport.sendMail(mailOptions, function (error, response) {
        if (error) {
            console.log(error);
        }
        else {
            console.log("mail sent");
        }
    });

在我的应用程序中工作

您可能需要在您的 Gmail 帐户中“允许不太安全的应用程序”(它一直在底部)。 您可能还需要“允许访问您的 Google 帐户”。 您可能还需要“允许访问您的 Google 帐户”。

这是我的Nodemailer 配置,经过一些研究后工作。

第 1 步:启用 lesssecureapp

https://www.google.com/settings/security/lesssecureapps 

第 2 步:Gmail 的 Nodemailer 配置

设置传输器:传输器将成为可以发送邮件的对象。 它是传输配置对象、连接 URL 或传输插件实例

let transporter = nodemailer.createTransport({
    service: 'gmail',                              // the service used
    auth: {
        user: process.env.EMAIL_FROM,              // authentication details of sender, here the details are coming from .env file
        pass: process.env.EMAIL_FROM_PASSWORD,
    },
});

写消息

const message = {
    from: 'myemail@gmail.com',                         // sender email address
    to: "receiver@example.com, receiver2@gmail.com",   // reciever email address
    subject: `The subject goes here`,
    html: `The body of the email goes here in HTML`,
    attachments: [
    {
      filename: `${name}.pdf`,
      path: path.join(__dirname, `../../src/assets/books/${name}.pdf`),
      contentType: 'application/pdf',
    },
  ],

发送邮件

transporter.sendMail(message, function (err, info) {
    if (err) {                                            // if error
        console.log(err);
    } else {
        console.log(info);                                // if success
    }
});

在生产环境中运行 Vercel lambda 时,我也遇到了 nodemailer 电子邮件发送的问题。

在我的情况下解决它的是等待 sendMail Promise 解决。

我还添加了 nodemailer-smtp-transport 就像在这个线程中建议的那样,但我认为它没有什么不同。

这是我的整个功能:

const nodemailer = require('nodemailer');
const smtpTransport = require('nodemailer-smtp-transport');


const transporter = nodemailer.createTransport(smtpTransport({
    service: 'gmail',
    auth: {
        user: '***@gmail.com',
        pass: process.env.SMTP_PASSWORD,
    },
}));


async function contact(req: any, res: any) {
    try {
        const response = await transporter.sendMail({
            from: '"*** <***gmail.com>', // sender address
            to: "***@gmail.com", // list of receivers
            subject: `***`, // Subject line
            html: `${req.body.message}<br/><br/>${req.body.firstname} ${req.body.lastname} - <b>${req.body.email}</b>`, // html body
        });
    } catch (error: any) {
        console.log(error);
        return res.status(error.statusCode || 500).json({ error: error.message });
    }

    return res.status(200).json({ error: "" });
}

export default contact;

Google 已禁用不太安全的应用程序访问,以下是在 Nodejs 中使用 Gmail 的新流程

  1. 现在您必须在 Google 中启用两步验证(如何启用两步验证
  2. 您需要生成应用专用密码。 转到Google 我的帐户 > 安全性
  3. 点击应用密码 > 选择其他,您将获得应用密码
  4. 您可以使用带有电子邮件和应用程序密码的普通 smtp。

gmail 不再支持不太安全的选项。

对于从第三方发送电子邮件,gmail 也不允许使用其用户密码

您现在应该使用应用密码来解决此问题。 希望此链接有助于设置您的应用密码。 https://support.google.com/mail/answer/185833?hl=en

gmail 不再支持这种方法

在此处输入图像描述

在此处输入图像描述

正如 Yaach 指出的那样,截至 2022 年 5 月 30 日,Google 不再支持不太安全的应用程序,而是切换到他们自己的Gmail API

这是 Gmail SMTP 和 nodemailer 的示例代码。

"use strict";
const nodemailer = require("nodemailer");

async function main() {
    let transporter = nodemailer.createTransport({
        host: "smtp.gmail.com",
        transportMethod: "SMTP",
        secureConnection: true,
        port: 465,
        secure: true, // upgrade later with STARTTLS
        auth: {
            user: "yourEmail@gmail.com",
            pass: "Your App  Specific password",
        },
    });

    let info = await transporter.sendMail(
        {
            from: "yourEmail@gmail.com",
            to: "to@gmail.com",
            subject: "Testing Message Message",
            text: "I hope this message gets delivered!",
            html: "<b>Hello world?</b>", // html body
        },
        (err, info) => {
            if (err) {
                console.log(err);
            } else {
                console.log(info.envelope);
                console.log(info.messageId);
            }
        }
    );
}

main();

谷歌不再提供启用“不太安全”的应用程序。 更好的方法是使用应用程序密码。 请参阅下面的 scipilot 答案。

我将其发布为答案,因为我仍然没有足够的代表发表评论。

还有另一个选项可以使用 SendGrid 进行电子邮件传递而不会失败。 很多时候,Nodemailer 会给出可能经常发生的邮件失败。

Nodemailer可以在链接中找到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM