提问人:Stephen Scott Moore 提问时间:11/8/2023 更新时间:11/8/2023 访问量:37
Nodemailer - 服务器上缺少“普通”的凭据
Nodemailer - Missing credentials for "Plain" on server
问:
我在 DigitalOean 的应用程序平台上有一个 mern 应用程序。如果用户注册,他们会收到一封欢迎电子邮件,要求他们验证其电子邮件地址。如果他们不这样做,当他们登录时,他们会在个人资料页面上看到一个按钮,用于重新发送验证电子邮件。
我正在使用 nodemailer 发送电子邮件,目前通过我的个人帐户(稍后会更改)。它适用于本地主机和 Render.com 但在数字海洋上,我收到以下错误:
Error: Missing credentials for "PLAIN"
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection._formatError (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:790:19)
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection.login (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:444:38)
[mat-scout] [2023-11-08 02:05:49] at /workspace/node_modules/nodemailer/lib/smtp-transport/index.js:272:32
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection.<anonymous> (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:213:17)
[mat-scout] [2023-11-08 02:05:49] at Object.onceWrapper (node:events:627:28)
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection.emit (node:events:513:28)
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection._actionEHLO (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:1347:14)
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection._processResponse (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:969:20)
[mat-scout] [2023-11-08 02:05:49] at SMTPConnection._onData (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:755:14)
[mat-scout] [2023-11-08 02:05:49] at TLSSocket.SMTPConnection._onSocketData (/workspace/node_modules/nodemailer/lib/smtp-connection/index.js:193:44) {
[mat-scout] [2023-11-08 02:05:49] code: 'EAUTH',
[mat-scout] [2023-11-08 02:05:49] command: 'API'
[mat-scout] [2023-11-08 02:05:49] }
我现在尝试添加文本:“Hello World”,但我仍然收到错误。下面是 mail.js 文件:
import nodemailer from "nodemailer";
import path from "path";
import { fileURLToPath } from "url";
import { generateTemplate } from "../mail/template.js";
const generateMailTransporter = () => {
let transport = nodemailer.createTransport({
host: "smtp.comcast.net",
port: 587,
secure: false,
auth: {
user: process.env.EMAIL,
pass: process.env.EMAIL_PASS,
},
});
return transport;
};
export const sendVerificationEmail = async (token, link, profile) => {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const transport = generateMailTransporter();
const { firstName, email } = profile;
const welcomeMessage = `Hi ${firstName}, welcome to ! There are so many features available to verified users. Use the given OTP (One-Time-Password) to verify your email.`;
transport.sendMail({
to: email,
from: process.env.VERIFICATION_EMAIL,
subject: "Welcome to MatScout",
text: "hello world",
html: generateTemplate({
title: "Welcome to MatScout",
message: welcomeMessage,
logo: "cid:logo",
banner: "cid:welcome",
link,
btnTitle: "Verify Your Email",
}),
attachments: [
{
fileName: "logo.png",
path: path.join(__dirname, "../mail/logo.png"),
cid: "logo",
},
{
fileName: "welcome.png",
path: path.join(__dirname, "../mail/welcome.png"),
cid: "welcome",
},
],
});
};
export const sendForgotPasswordLink = async (link, profile) => {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const transport = generateMailTransporter();
const { email } = profile;
const message = `We just received a request to reset your password. Use the link beloow to create a new password. <br><br> If you did not send this request, it means someone is trying to access your account and you can disregard this email.`;
async function main() {
let info = await transport.sendMail({
to: email,
from: process.env.VERIFICATION_EMAIL,
subject: "Reset Password Link",
text: "hello world",
html: generateTemplate({
title: "Forgot Password",
message,
logo: "cid:logo",
banner: "cid:forget_password",
link,
btnTitle: "ResetPassword",
}),
attachments: [
{
fileName: "logo.png",
path: path.join(__dirname, "../mail/logo.png"),
cid: "logo",
},
{
filename: "forget_password.png",
path: path.join(__dirname, "../mail/forget_password.png"),
cid: "forget_password",
},
],
});
}
main().catch(console.error);
};
export const sendPassResetSuccessEmail = async (firstName, email) => {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const transport = generateMailTransporter();
const message = `Dear ${firstName}, your password has just been reset successfuly. You can now sign in with your new password.`;
transport.sendMail({
to: email,
from: process.env.VERIFICATION_EMAIL,
subject: "Password Reset Successfully!",
text: "hello world",
html: generateTemplate({
title: "Password Reset Successfully",
message,
logo: "cid:logo",
banner: "cid:forget_password",
link: process.env.SIGN_IN_URL,
btnTitle: "Sign In",
}),
attachments: [
{
fileName: "logo.png",
path: path.join(__dirname, "../mail/logo.png"),
cid: "logo",
},
{
filename: "forget_password.png",
path: path.join(__dirname, "../mail/forget_password.png"),
cid: "forgot_password",
},
],
});
};
答:
0赞
James Hibbard
11/8/2023
#1
该错误消息表明未向 SMTP 服务器正确提供身份验证详细信息。你能在函数内将它们正确地记录到控制台吗?generateMailTransporter
例如:
const generateMailTransporter = () => {
// What does the following output?
console.log('Email:', process.env.EMAIL);
console.log('Email Pass:', process.env.EMAIL_PASS);
let transport = nodemailer.createTransport({
host: "smtp.comcast.net",
port: 587,
secure: false,
auth: {
user: process.env.EMAIL,
pass: process.env.EMAIL_PASS,
},
});
return transport;
};
如果记录正确,我唯一想到的其他事情是:
a) 一些电子邮件提供商限制来自云平台的 SMTP 访问以防止滥用。您可能需要使用专用的事务性电子邮件服务,例如 SendGrid。
b) 在 DigitalOcean 的应用平台上,您可以在应用规范中或通过应用的设置选项卡设置环境变量(秘密)。验证这些设置是否正确,并且此处没有任何冲突。
HTH型
评论
0赞
Stephen Scott Moore
11/9/2023
非常感谢!
评论
generateMailTransporter