Missing credentials for "PLAIN" nodemailer
Solution 1
You have
auth: {
user: '[email protected]',
password: 'password'
}
But you should write this
auth: {
user: '[email protected]',
pass: 'password'
}
Just rename password to pass.
Solution 2
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.
Solution 3
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"
}
});
Solution 4
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
Solution 5
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.
igolo
Updated on June 17, 2021Comments
-
igolo almost 3 years
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.