缺少“PLAIN”节点邮件程序的凭据

Posted

技术标签:

【中文标题】缺少“PLAIN”节点邮件程序的凭据【英文标题】:Missing credentials for "PLAIN" nodemailer 【发布时间】:2018-07-28 23:22:24 【问题描述】:

我正在尝试在我的联系表单中使用 nodemailer 来接收反馈并将它们直接发送到电子邮件。这是下面的表格。

<form method="post" action="/contact">
      <label for="name">Name:</label>
      <input type="text" name="name" placeholder="Enter Your Name" required><br>
      <label for="email">Email:</label>
      <input type="email" name="email" placeholder="Enter Your Email" required><br>
      <label for="feedback">Feedback:</label>
      <textarea name="feedback" placeholder="Enter Feedback Here"></textarea><br>
      <input type="submit" name="sumbit" value="Submit">
</form>

这是服务器端的请求的样子

app.post('/contact',(req,res)=>
let transporter = nodemailer.createTransport(
    service: 'gmail',
    auth: 
        user: 'user@gmail.com',
        password: 'password'
    
);
var mailOptions = 
    from: req.body.name + '&lt;' + req.body.email + '&gt;',
    to: 'bantspl@gmail.com',
    subject: 'Plbants Feedback',
    text: req.body.feedback 
;
transporter.sendMail(mailOptions,(err,res)=>
    if(err)
        console.log(err);
    
    else 

    
);

我收到错误 Missing credentials for "PLAIN"。任何帮助表示赞赏,非常感谢。

【问题讨论】:

【参考方案1】:

我在将我的应用部署到 Heroku 时遇到了这个问题。我在本地发送电子邮件很好,但是当我将新版本推送到 Heroku 时,我收到了可怕的 Missing credentials for "PLAIN" 错误。我的问题是我没有在 Heroku 中单独设置 .env 变量。

如果您访问 Heroku 中的仪表板,您可以手动设置配置变量,这为我解决了问题。

或者您可以通过 Heroku CLI 进行操作 - 好 tutorial here

【讨论】:

【参考方案2】:

我遇到了同样的问题,那是谷歌自动阻止了你的登录表单不真实的第三方软件造成的。然后,您只需在 Google 帐户管理中关闭此功能即可。

问候,

【讨论】:

【参考方案3】:

对我来说,问题是我没有正确访问 .env 文件变量(我假设您也将电子邮件和密码存储在 .env 文件中)。我不得不将它添加到文件的顶部:

const dotenv = require('dotenv');
dotenv.config();

一旦我这样做了,我就可以像这样填写凭据的“auth”部分:

auth: 
  user: process.env.EMAIL_USERNAME,
  pass: process.env.EMAIL_PASSWORD

当然,您需要将 EMAIL_USERNAME 和 EMAIL_PASSWORD 替换为您在 .env 文件中调用这些变量的任何名称。

【讨论】:

【参考方案4】:

如果您要使用基本身份验证(您当前的配置),您需要从以下链接激活less secure app 访问您的谷歌帐户,该链接在节点邮件站点here 中声明。

另外,为了更安全,我建议查看以下两个链接:

Sending Emails Securely Using Node.js, Nodemailer, SMTP, Gmail, and OAuth2 这将向您解释简单/基本和安全的方法。 Using OAuth2 in nodemailer official docs,其中包含更简化版本的安全方法(但您需要按照第一个链接中提到的步骤操作,直到获得 client_ID、client_Secret、Refresh_Token 和 Access Token 后再继续操作)。

注意:如果您要使用第一个链接步骤中的安全方式,您应该修改 auth 属性以添加 type 选项,如下所示:

身份验证: 类型:'OAuth2', 用户:process.env.EMAIL, 访问令牌, clientId: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, refresh_token:process.env.REFRESH_TOKEN

因为没有明确说明您正在使用 OAuth2 方法,它会向您打印相同的错误(基于我最近使用该链接中的书面代码进行的试验)

【讨论】:

【参考方案5】:

我在没有 .env 文件的文件夹中运行 ts-node。

所以我的process.env.GMAIL_EMAILprocess.env.GMAIL_PASS 没有定义。

当我在带有.env 的目录中运行它时,它起作用了

【讨论】:

【参考方案6】:

对我来说,这是因为我忘记了 npm install dotenvrequire('dotenv').config();

【讨论】:

【参考方案7】:

我们不需要为此降低 Google 帐户安全性。这适用于本地主机和实时服务器。版本:node12.18.4,nodemailer^6.4.11

第 1 步: 按照此视频中设置您的 Google Api 访问权限并忽略他的代码(它对我不起作用):https://www.youtube.com/watch?v=JJ44WA_eV8E

第 2 步: 在您通过npm i nodemailer dotenv 安装 nodemailer 和 dotenv 后,在您的主应用程序文件中尝试此代码:

    require('dotenv').config();  //import and config dotenv to use .env file for secrets
    const nodemailer = require('nodemailer');

    function sendMessage() 
      try 
        // mail options
        const mailOptions = 
          from: "MySite@mysite.com",
          to: "my_gmail@gmail.com",
          subject: "Hey there!",
          text: "Whoa! It freakin works now."
        ;
        // here we actually send it
        transporter.sendMail(mailOptions, function(err, info) 
          if (err) 
            console.log("Error sending message: " + err);
           else 
            // no errors, it worked
            console.log("Message sent succesfully.");
          
        );
       catch (error) 
        console.log("Other error sending message: " + error);
      
    

    // thats the key part, without all these it didn't work for me
    let transporter = nodemailer.createTransport(
      host: 'smtp.gmail.com',
      port: 465,
      secure: true,
      service: 'gmail',
      auth: 
            type: "OAUTH2",
            user: process.env.GMAIL_USERNAME,  //set these in your .env file
            clientId: process.env.OAUTH_CLIENT_ID,
            clientSecret: process.env.OAUTH_CLIENT_SECRET,
            refreshToken: process.env.OAUTH_REFRESH_TOKEN,
            accessToken: process.env.OAUTH_ACCESS_TOKEN,
            expires: 3599
      
    );

    // invoke sending function
    sendMessage();

上述代码的.env 文件应该类似于:

GMAIL_USERNAME=your_mail@gmail.com
GMAIL_PASSWORD=lakjrfnk;wrh2poir2039r
OAUTH_CLIENT_ID=vfo9u2o435uk2jjfvlfdkpg284u3.apps.googleusercontent.com
OAUTH_CLIENT_SECRET=og029503irgier0oifwori
OAUTH_REFRESH_TOKEN=2093402i3jflj;geijgp039485puihsg[-9a[3;wjenjk,ucv[3485p0o485uyr;ifasjsdo283wefwf345w]fw2984329oshfsh
OAUTH_ACCESS_TOKEN=owiejfw84u92873598yiuhvsldiis9er0235983isudhfdosudv3k798qlk3j4094too283982fs

【讨论】:

你知道当你搜索这个简单的解决方案 2 天并没有找到任何东西时的感觉。当你在这里发布它时,你会看到上面的 3 个人已经发布了它,而你之前没有看到它! :-P【参考方案8】:

对我来说,这是因为我忘记将 Gmail 密码 添加到我的 .env 文件中。

【讨论】:

【参考方案9】:

你有

auth: 
    user: 'user@gmail.com',
    password: 'password'

但你应该写这个

auth: 
    user: 'user@gmail.com',
    pass: 'password'

只需重命名密码即可通过。

【讨论】:

你应该得到一个奖项!这救了我谢谢 简单直接,活生生的救星。只需重命名密码即可通过。解决了这个问题。您可能错误地写了密码而不是直接通过【参考方案10】:

我能够通过使用数字 3 来解决这个问题,设置 3LO 身份验证,来自 nodemailer 文档的示例(链接:https://nodemailer.com/smtp/oauth2/)。我的代码如下所示:

let transporter = nodemailer.createTransport(
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: 
        type: 'OAuth2',
        user: 'user@example.com',
        clientId: '000000000000-xxx0.apps.googleusercontent.com',
        clientSecret: 'XxxxxXXxX0xxxxxxxx0XXxX0',
        refreshToken: '1/XXxXxsss-xxxXXXXXxXxx0XXXxxXXx0x00xxx',
        accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x'
    
);

如果您查看我上面提到的链接中的示例,您会看到那里有一个“过期”属性,但在我的代码中我没有包含它,它仍然可以正常工作。

为了获取clientId、clientSecret、refreshToken和accessToken,我刚刚看了这个视频https://www.youtube.com/watch?v=JJ44WA_eV8E。

我不知道这对你是否仍然有帮助。

【讨论】:

在这里您可以找到一个不错的更新视频:youtube.com/watch?v=-rcRf7yswfM【参考方案11】:

Gmail / Google 应用电子邮件服务需要 OAuth2 进行身份验证。纯文本密码需要在 google 帐户上手动禁用安全功能。

要在 Nodemailer 中使用 OAuth2,请参考:https://nodemailer.com/smtp/oauth2/

示例代码:

var email_smtp = nodemailer.createTransport(      
  host: "smtp.gmail.com",
  auth: 
    type: "OAuth2",
    user: "youremail@gmail.com",
    clientId: "CLIENT_ID_HERE",
    clientSecret: "CLIENT_SECRET_HERE",
    refreshToken: "REFRESH_TOKEN_HERE"                              
  
);

如果您仍然只想使用纯文本密码,请在您的 google 帐户上禁用安全登录并使用如下:

var email_smtp = nodemailer.createTransport(      
  host: "smtp.gmail.com",
  auth: 
    type: "login", // default
    user: "youremail@gmail.com",
    pass: "PASSWORD_HERE"
  
);

【讨论】:

以前版本的 Nodemailer(不确定哪个版本)需要使用 xoauth2.createXOAuth2Generator 来处理 OAuth2。不再需要它。

以上是关于缺少“PLAIN”节点邮件程序的凭据的主要内容,如果未能解决你的问题,请参考以下文章

Next-Auth:如何使用电子邮件 + 密码凭据提供程序处理注册?

在 Python 中发送带有 HTML+plain_text 电子邮件的 PDF 附件

在带有附件的电子邮件中将内容类型从 text/plain 转换为 text/html

使用流明发送电子邮件,而不在 env 文件中设置 smtp 凭据

如何实现电子邮件验证组件

代表其他用户发送电子邮件