Nodemailer使用教程:在Node.js中发送电子邮件

时间:2024-11-27 06:58:42

目录

1. 简介

2. 安装

3. 基本配置

3.1 创建传输器

3.2 配置说明

4. 发送邮件

4.1 基本发送示例

4.2 发送验证码示例

5. 常见问题解决

5.1 "Greeting never received" 错误

5.2 安全建议

SMTP与邮件加密协议详解 

1. SMTP简介

1.1 基本特点

2. 加密协议对比

2.1 SSL/TLS (端口465)

 2.2 STARTTLS (端口587)

3. 端口使用建议

3.1 常用端口对比

3.2 选择建议

4. 安全性考虑

4.1 SSL/TLS (465端口)优势

4.2 STARTTLS (587端口)注意事项

5. 常见邮件服务商配置

5.1 Gmail

5.2 Outlook/Office365

5.3 QQ邮箱


 

1. 简介

Nodemailer是Node.js平台上最流行的电子邮件发送库,它提供了一个简单而强大的解决方案,支持Unicode内容、HTML内容、附件、图片嵌入等功能。

2. 安装

首先需要安装Nodemailer包:
 

npm install nodemailer

3. 基本配置

3.1 创建传输器

首先需要创建一个传输器(transporter),这是发送邮件的核心配置:
 

const nodemailer = require("nodemailer");

const transporter = nodemailer.createTransport({
  host: "smtp.example.com",     // SMTP服务器地址
  port: 465,                    // SMTP端口
  secure: true,                 // 使用SSL/TLS
  auth: {
    user: "your-email@example.com",  // 邮箱账号
    pass: "your-password"            // 邮箱密码或应用专用密码
  }
});

3.2 配置说明

host: SMTP服务器地址

port: 常用端口

  • 465 (SSL/TLS)
  • 587 (STARTTLS)

secure:

  • true: 使用465端口
  • false: 使用其他端口

auth: 认证信息
 

4. 发送邮件

4.1 基本发送示例

async function sendEmail(to, subject, content) {
  const mailOptions = {
    from: '"发送者名称" <sender@example.com>',  // 发件人
    to: to,                                     // 收件人
    subject: subject,                           // 主题
    text: content,                             // 纯文本内容
    html: `<b>${content}</b>`                  // HTML内容
  };

  try {
    const info = await transporter.sendMail(mailOptions);
    console.log("邮件发送成功:", info.messageId);
    return info;
  } catch (error) {
    console.error("邮件发送失败:", error);
    throw error;
  }
}

4.2 发送验证码示例

以下是一个完整的发送验证码的实现:
 

const nodemailer = require("nodemailer");

const transporter = nodemailer.createTransport({
  host: MAIL_HOST,    
  port: MAIL_PORT,    
  secure: true,       
  auth: {
    user: MAIL_USER,  
    pass: MAIL_PWD,   
  }
});

const sendMail = async (to, subject, html) => {
  const mailOptions = {
    from: MAIL_USER,  // 发送者
    to,              // 接收者
    subject,         // 主题
    html,           // HTML内容
  };
  return await transporter.sendMail(mailOptions);
};

在控制器中使用:

async sendEmailCode(ctx, next) {
  const { email } = ctx.request.body;
  
  // 生成6位随机验证码
  const code = Math.random().toString().slice(2, 8);
  
  // 构建HTML模板
  const html = `
    <p>你好!</p>
    <p>您正在注册社区账号</p>
    <p>你的验证码是:<strong style="color: #ff4e2a;">${code}</strong></p>
    <p>***该验证码5分钟内有效***</p>
  `;

  try {
    // 发送邮件
    await sendMail(email, "验证码", html);
    
    // 存储验证码(使用Redis)
    const emailCodeKey = `email:${email}`;
    await Redis.set(emailCodeKey, code, 60 * 5);

    ctx.body = {
      code: 0,
      message: "发送邮箱验证码成功",
      result: ""
    };
  } catch (error) {
    ctx.body = {
      code: -1,
      message: "发送邮箱验证码失败",
      error: error.message
    };
  }
}

 

5. 常见问题解决

5.1 "Greeting never received" 错误

如果遇到"Greeting never received"错误,通常有以下解决方案:

  • 检查端口配置:
{
  port: 465,  // SSL
  secure: true
}
// 或
{
  port: 587,  // STARTTLS
  secure: false
}

 

  • 检查网络连接
  • 确认服务器设置是否正确

4. 验证认证信息是否正确

5.2 安全建议

  • 使用环境变量存储敏感信息
  • 启用SSL/TLS加密
  • 使用应用专用密码而不是邮箱密码
  • 设置合理的超时时间

 

SMTP与邮件加密协议详解 

1. SMTP简介

SMTP (Simple Mail Transfer Protocol,简单邮件传输协议) 是一个在互联网上发送电子邮件的标准协议。

1.1 基本特点

  • 默认使用25端口(未加密)
  • 以纯文本形式传输数据
  • 没有加密保护,容易被截获

2. 加密协议对比

2.1 SSL/TLS (端口465)

const transporter = nodemailer.createTransport({
  host: "smtp.example.com",
  port: 465,
  secure: true,  // 启用SSL/TLS
  auth: {
    user: "your-email@example.com",
    pass: "your-password"
  }
});

特点:

  • 全程加密通信
  • 连接建立时就启用加密
  • 更安全,是推荐的加密方式
  • 适用于现代邮件系统

工作流程:

  • 客户端连接到服务器的465端口
  • 立即建立SSL/TLS加密通道
  • 所有后续通信都在加密通道中进行

 2.2 STARTTLS (端口587)

const transporter = nodemailer.createTransport({
  host: "smtp.example.com",
  port: 587,
  secure: false,  // 使用STARTTLS
  auth: {
    user: "your-email@example.com",
    pass: "your-password"
  }
});

 

特点:

  • 先以明文方式建立连接
  • 通过STARTTLS命令升级为加密连接
  • 向后兼容性更好
  • 适用于一些旧的邮件系统

工作流程:

1. 客户端以明文方式连接到587端口

  • 服务器告知支持STARTTLS
  • 客户端发送STARTTLS命令
  • 连接升级为加密连接
  • 继续后续通信

3. 端口使用建议

3.1 常用端口对比

| 端口 | 协议 | 加密方式 | 建议 |

|------|------|----------|------|

| 25 | SMTP | 无加密 | 不推荐使用 |

| 465 | SMTPS | SSL/TLS | 推荐使用 |

| 587 | SMTP | STARTTLS | 备选方案 |

3.2 选择建议

// 推荐配置(使用465端口)
const secureConfig = {
  host: "smtp.example.com",
  port: 465,
  secure: true,
  auth: {
    user: "your-email@example.com",
    pass: "your-password"
  }
};

// 备选配置(使用587端口)
const starttlsConfig = {
  host: "smtp.example.com",
  port: 587,
  secure: false,
  requireTLS: true,  // 强制要求TLS
  auth: {
    user: "your-email@example.com",
    pass: "your-password"
  }
};

 

4. 安全性考虑

4.1 SSL/TLS (465端口)优势

  • 全程加密,无明文传输风险
  • 连接建立更快
  • 现代邮件服务器普遍支持
  • 不存在降级攻击风险

4.2 STARTTLS (587端口)注意事项

  • 初始连接为明文
  • 可能受到降级攻击
  • 需要额外的STARTTLS协商过程
  • 配置时建议启用requireTLS选项
// STARTTLS的安全配置
const secureStartTLS = {
  host: "smtp.example.com",
  port: 587,
  secure: false,
  requireTLS: true,
  tls: {
    rejectUnauthorized: true,  // 验证服务器证书
    minVersion: "TLSv1.2"      // 最低TLS版本
  }
};

5. 常见邮件服务商配置

5.1 Gmail

{
  host: "smtp.gmail.com",
  port: 465,
  secure: true
}

5.2 Outlook/Office365

{
  host: "smtp.office365.com",
  port: 587,
  secure: false,
  requireTLS: true
}

5.3 QQ邮箱

{
  host: "smtp.qq.com",
  port: 465,
  secure: true
}

通过了解这些区别,你可以根据具体需求选择合适的配置。一般情况下,如果邮件服务器支持465端口的SSL/TLS,建议优先使用这种方式,因为它更安全且效率更高。