缺少“普通”的凭据。 Nodemailer

发布于 2025-01-31 06:50:32 字数 1483 浏览 5 评论 0 原文

我正在尝试使用联系表中的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: '[email protected]',
        password: 'password'
    }
});
var mailOptions = {
    from: req.body.name + '&lt;' + req.body.email + '&gt;',
    to: '[email protected]',
    subject: 'Plbants Feedback',
    text: req.body.feedback 
};
transporter.sendMail(mailOptions,(err,res)=>{
    if(err){
        console.log(err);
    }
    else {

    }
});

我会收到错误缺少“ Plain” 的凭据。任何帮助都将受到赞赏,非常感谢。

I'm trying to use nodemailer in my contact form to receive feedback and send them directly to an email. This is the form below.

<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>

This is what the request in the server side looks like

app.post('/contact',(req,res)=>{
let transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '[email protected]',
        password: 'password'
    }
});
var mailOptions = {
    from: req.body.name + '<' + req.body.email + '>',
    to: '[email protected]',
    subject: 'Plbants Feedback',
    text: req.body.feedback 
};
transporter.sendMail(mailOptions,(err,res)=>{
    if(err){
        console.log(err);
    }
    else {

    }
});

I'm getting the error Missing credentials for "PLAIN". Any help is appreciated, thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

青春有你 2025-02-07 06:50:32

您有

auth: {
    user: '[email protected]',
    password: 'password'
}

,但您应该写这

auth: {
    user: '[email protected]',
    pass: 'password'
}

简单的密码即可通过。

You have

auth: {
    user: '[email protected]',
    password: 'password'
}

But you should write this

auth: {
    user: '[email protected]',
    pass: 'password'
}

Just rename password to pass.

梦幻的味道 2025-02-07 06:50:32

我能够通过使用数字3,设置3LO身份验证来解决此问题://nodemailer.com/smtp/oauth2/ )。我的代码看起来像这样:

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

如果您在上面说明的链接中查看了示例,则可以看到那里有一个“有效期”的属性,但是在我的代码中,我没有包含它,并且仍然可以正常工作。

为了获取客户端,clientsecret,刷新和访问权限,我刚刚观看了此视频

我不知道这是否对您有帮助。

I was able to solve this problem by using number 3, Set up 3LO authentication, example from the nodemailer documentation (link: https://nodemailer.com/smtp/oauth2/). My code looks like this:

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

If you looked at the example in the link that I stated above, you can see there that there is a 'expires' property but in my code i didn't include it and it still works fine.

To get the clientId, clientSecret, refreshToken, and accessToken, I just watched this video https://www.youtube.com/watch?v=JJ44WA_eV8E .

I don't know if this is still helpful to you tho.

潜移默化 2025-02-07 06:50:32

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

要在NodeMailer中使用OAuth2,请参阅:

” :

var email_smtp = nodemailer.createTransport({      
  host: "smtp.gmail.com",
  auth: {
    type: "OAuth2",
    user: "[email protected]",
    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: "[email protected]",
    pass: "PASSWORD_HERE"
  }
});

Gmail / Google app email service requires OAuth2 for authentication. PLAIN text password will require disabling security features manually on the google account.

To use OAuth2 in Nodemailer, refer: https://nodemailer.com/smtp/oauth2/

Sample code:

var email_smtp = nodemailer.createTransport({      
  host: "smtp.gmail.com",
  auth: {
    type: "OAuth2",
    user: "[email protected]",
    clientId: "CLIENT_ID_HERE",
    clientSecret: "CLIENT_SECRET_HERE",
    refreshToken: "REFRESH_TOKEN_HERE"                              
  }
});

And if you still want to use just plain text password, disable secure login on your google account and use as follows:

var email_smtp = nodemailer.createTransport({      
  host: "smtp.gmail.com",
  auth: {
    type: "login", // default
    user: "[email protected]",
    pass: "PASSWORD_HERE"
  }
});
驱逐舰岛风号 2025-02-07 06:50:32

对我来说,问题是我无法正确访问.ENV文件变量(我假设您也将电子邮件和密码存储在.env文件中)。我必须将其添加到文件的顶部:

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

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

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

当然,您需要用任何称为.env中的变量来替换email_username和email_password文件。

For me the issue was that I wasn't accessing the .env file variables properly (I assume you're storing your email and password in a .env file too). I had to add this to the top of the file:

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

Once I did that I could fill out the "auth" portion of the credentials like this:

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

Of course you need to replace EMAIL_USERNAME and EMAIL_PASSWORD with whatever you called those variables in your .env file.

滥情空心 2025-02-07 06:50:32

我们无需为此降低我们的Google帐户安全性。这对我在Localhost和Live Server上工作。版本:节点 12.18.4 ,NodeMailer ^6.4.11

步骤1:
跟随此视频中设置Google API访问并忽略他的代码(对我不起作用): https://www.youtube.com/watch?v=jj44wa_ev8e

步骤2:
通过 npm i 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: "[email protected]",
          to: "[email protected]",
          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 文件>上述代码的文件,请在主应用程序文件中尝试此代码。

[email protected]
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

We don't need to lower our Google Account Security for this. This works for me on localhost and live server. Versions: node 12.18.4, nodemailer ^6.4.11.

STEP 1:
Follow setting up your Google Api Access in this video AND IGNORE his code (it didn't work for me): https://www.youtube.com/watch?v=JJ44WA_eV8E

STEP 2:
Try this code in your main app file after you install nodemailer and dotenv via npm i 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: "[email protected]",
          to: "[email protected]",
          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();

Your .env file for the above code should look similar to this:

[email protected]
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
独留℉清风醉 2025-02-07 06:50:32

当我尝试将邮件发送到 mailhog 时,这发生在我身上。默认情况下不使用不使用用户名/密码。

我的代码提供了空的用户名/密码,但实际上您根本不提供凭据。

这不起作用(导致“缺少“普通”的凭证'):

const transport = require('nodemailer').createTransport({
  host: mailhog,
  port: 1025,
  secure: false,
  auth: {
    user: '',
    pass: '',
  },
});

但这有效:

const transport = require('nodemailer').createTransport({
  host: mailhog,
  port: 1025,
  secure: false,
});

This happened to me when I tried to send mail to MailHog, a development local mailserver which runs on port 1025, and uses no username/password by default.

My code was providing empty username/password, but in fact you should provide no credentials at all.

This does not work (results in 'Missing credentials for "PLAIN"'):

const transport = require('nodemailer').createTransport({
  host: mailhog,
  port: 1025,
  secure: false,
  auth: {
    user: '',
    pass: '',
  },
});

But this works:

const transport = require('nodemailer').createTransport({
  host: mailhog,
  port: 1025,
  secure: false,
});
耀眼的星火 2025-02-07 06:50:32

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

For me it happened because I forgot to npm install dotenv and require('dotenv').config();

_畞蕅 2025-02-07 06:50:32

当我的应用程序部署到Heroku时,我遇到了这个问题。我在本地发送电子邮件正常,但是当我将新构建推向Heroku时,我得到了可怕的缺少“ Plain” 错误的凭据。我的问题是我没有在Heroku中单独设置.ENV变量。

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

或者,您可以通过Heroku Cli -good tutorial>

//i.sstatic.net/swtzt.png“ rel =“ nofollow noreferrer”>

I came across this issue when deploying my app to Heroku. I was sending emails fine locally, but when I pushed a new build to Heroku, I got the dreaded Missing credentials for "PLAIN" error. My issue was that I hadn't separately setup the .env variables in Heroku.

If you go to your dashboard in Heroku, you can manually set up the config variables and that solved the problem for me.

Or you can do via Heroku CLI - good tutorial here

Heroku Dashoard

小猫一只 2025-02-07 06:50:32

对我来说,这是因为我忘了在.env文件中添加 gmail密码

For me it was because I forgot to add my Gmail password to my .env file.

温柔戏命师 2025-02-07 06:50:32

我在没有.env文件的文件夹中运行TS节点。

因此,我的 process.env.gmail_email process.env.gmail_pass 未定义。

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

I was running ts-node in a folder that didn't have the .env file.

So my process.env.GMAIL_EMAIL and process.env.GMAIL_PASS weren't defined.

When I ran it in the directory with the .env, it worked

陈独秀 2025-02-07 06:50:32

如果要使用基本身份验证(当前配置),则需要激活较少安全的应用程序访问以下链接到您的Google帐户,该链接在Node Mailer网站

同样以更安全的方式,我建议您查看以下两个链接:

注意:如果要从第一个链接步骤中使用安全方法,则应修改auth属性以添加 type 选项,如下:

auth:{
类型:'oauth2',
用户:process.env.email,
AccessToken,
客户端:process.env.client_id,
客户端:process.env.client_secret,
refresh_token:process.env.refresh_token
}

因为如果不明确说明您正在使用oauth2方法,它将与您打印出相同的错误(根据我最近使用该链接中书面代码的试验)

If you are going to use the basic authentication (your current configuration) you will need to activate less secure app access from the following link to your google account which was stated in node mailer site here.

Also for more secure way, I recommend to take a look on the two following links:

Note: if you are going to use the secure way from the first link steps you should modify the auth attributes to add the type option like the following:

auth: {
type: 'OAuth2',
user: process.env.EMAIL,
accessToken,
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refresh_token: process.env.REFRESH_TOKEN
}

because without stating explicitly that you are using OAuth2 method it will print the same error to you (based on my recent trials using the written code in that link)

甜中书 2025-02-07 06:50:32

我在渲染服务器上也遇到了同样的问题,我自己的情况可以在任何服务器上发生。

我能够通过执行以下

来解决此问题

  • 记录运输对象
  • 检查所有属性和值是否在那里或正确
  • 然后我发现通过现场值显示不确定。
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,

}

  • 我后来发现我没有在渲染服务器上的环境变量中添加email_pass。
    添加后,我的问题得到了解决。

我希望这对某人有帮助

I had the same issue on render server and my own case can occur on any server.

I was able to fix this issue by doing the following

  • log the transporter object
  • check all the properties and values if its there or correct
  • then I discovered pass field value was showing undefined.
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,

}

  • I later discovered I didn't add Email_Pass in my local env variable to my environment variable on the render server.
    And after adding it my problem was solved.

I hope this is helpful to someone

恋你朝朝暮暮 2025-02-07 06:50:32

Google禁用较不安全的应用程序,以解决需要设置“使用应用程序密码登录” ,并允许应用程序密码“设置两个因素身份验证”

当2 step-verification打开并遇到“密码不正确”错误时,请登录到您的帐户并进入安全性,请尝试使用应用程序密码。

transport: {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: '[email protected]',
    pass: 'app password',
  },
},

Google disabled less secure apps, to resolve the issue one need to setup "Login with app password" and to allow the app password "setup two factor authentication"

when 2-Step-Verification is on and one get a "password incorrect" error, sign in to your account and go to security, try to use an App Password.

transport: {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: '[email protected]',
    pass: 'app password',
  },
},
余罪 2025-02-07 06:50:32

如果您期望此(错误发送错误:丢失“普通”错误的凭据)错误,则可能是因为您正在Localhost上测试。

例如,如果您使用的是Heroku,只需尝试部署项目并在生产中进行测试即可。

问候。

If you are expecting this (ERROR Send Error: Missing credentials for "PLAIN") error, it's probably because you are testing on localhost.

For example, if you are using Heroku, simply try to deploy your project and test it in production.

Regards.

围归者 2025-02-07 06:50:32
const sentEmail = async options =>{
    // 1) Create Transporter
    const transporter = nodemailer.createTransport({
        host: process.env.EMAIL_HOST,
        port: process.env.EMAIL_PORT,
        auth: {
            user: process.env.EMAIL_USERNAME,
            pass: process.env.EMAIL_PASSWORD
        }
    });

    // 2) Define the email options
    const mailOptions = {
        from: "Muhammad Waris <[email protected]>",
        to: options.email,
        subject: options.subject,
        text: options.message,
    }

    // 3) Send email
    transporter.verify(function(error, success) {
        if (error) {
            console.log('Server is not ready to take our messages', error);
        } else {
            console.log('Server is ready to take our messages');
        }
    });

    // 3) Send email
    await transporter.sendMail(mailOptions);
}


Use this method to send email 

   await sendEmail({
            email: user.email,
            subject: 'Your password reset token (valid for 10 min)',
            message
        }); 

    const message = `Forgot your password? Submit a PATCH request with your new password and passwordConfirm to: ${resetURL}.\nIf you didn't forget your password, please ignore this email!`
const sentEmail = async options =>{
    // 1) Create Transporter
    const transporter = nodemailer.createTransport({
        host: process.env.EMAIL_HOST,
        port: process.env.EMAIL_PORT,
        auth: {
            user: process.env.EMAIL_USERNAME,
            pass: process.env.EMAIL_PASSWORD
        }
    });

    // 2) Define the email options
    const mailOptions = {
        from: "Muhammad Waris <[email protected]>",
        to: options.email,
        subject: options.subject,
        text: options.message,
    }

    // 3) Send email
    transporter.verify(function(error, success) {
        if (error) {
            console.log('Server is not ready to take our messages', error);
        } else {
            console.log('Server is ready to take our messages');
        }
    });

    // 3) Send email
    await transporter.sendMail(mailOptions);
}


Use this method to send email 

   await sendEmail({
            email: user.email,
            subject: 'Your password reset token (valid for 10 min)',
            message
        }); 

    const message = `Forgot your password? Submit a PATCH request with your new password and passwordConfirm to: ${resetURL}.\nIf you didn't forget your password, please ignore this email!`
涫野音 2025-02-07 06:50:32

我遇到了同样的问题,这是由Google自动阻止您的登录表单不正确的第三方软件引起的。然后,您只需在Google帐户管理中关闭此功能即可。

问候,

I encountered the same problem, and that was caused by Google automatically blocked your logging-in form untruthful third-party software. Then you can just turn this feature off in your Google account management.

Regards,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文