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

目录

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/TLSauth: {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,  // SSLsecure: true
}
// 或
{port: 587,  // STARTTLSsecure: 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/TLSauth: {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,  // 使用STARTTLSauth: {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,  // 强制要求TLSauth: {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,建议优先使用这种方式,因为它更安全且效率更高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887934.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cause: java.sql.SQLException: No value specified for parameter 4

问题 执行更新sql时报错&#xff0c;异常栈如下 org.springframework.jdbc.BadSqlGrammarException: ### Error updating database. Cause: java.sql.SQLException: No value specified for parameter 4 ### The error may exist in com/my/mapper/MyMapper.java (best gue…

Wireshark 4.4.2:安全更新、错误修复、更新协议支持

流行的网络协议分析器Wireshark已更新至4.4.2版本。它可用于网络故障排除、分析、开发和教育。 已修复以下漏洞&#xff1a; wnpa-sec-2024-14 FiveCo RAP 解剖器无限循环。wnpa-sec-2024-15 ECMP 解析器崩溃。 更新的协议支持&#xff1a; ARTNET、ASN.1 PER、BACapp、B…

【一维DP】【三种解法】力扣983. 最低票价

在一个火车旅行很受欢迎的国度&#xff0c;你提前一年计划了一些火车旅行。在接下来的一年里&#xff0c;你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车票有 三种不同的销售方式 &#xff1a; 一张 为期一天 的通行证售价为 costs[0] …

C语言中数据类型对应的打印格式

提示&#xff1a;文章 文章目录 前言一、背景二、C语言中数据类型对应的打印格式三、3.1 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 最近 二、C语言中数据类型对应的打印格式 int 对应 %d long 对应 %ld char 对应 %c float 对应 %f long long 对应 %…

《Django 5 By Example》阅读笔记:p339-p358

《Django 5 By Example》学习第12天&#xff0c;p339-p358总结&#xff0c;总计20页。 一、技术总结 1.项目(购物网站) django-admin startproject myshop 虽然这里只是示例&#xff0c;但我觉得这种命名为 myxxx 的习惯非常不好&#xff0c;因为在实际应用中&#xff0c;是…

Vue 项目开发常用知识点

一、基础语法与指令 1. 插值表达式 插值表达式是 Vue 中最基础的数据绑定方式&#xff0c;使用双大括号{{ }}将数据包裹起来&#xff0c;例如{{ message }}&#xff0c;它会将 Vue 实例中的message属性的值渲染到页面相应位置。这种方式可以方便地在页面中展示动态数据&#x…

【Web开发基础学习——corsheaders 应用的理解】

Web开发基础学习系列文章目录 第一章 基础知识学习之corsheaders 应用的理解 文章目录 Web开发基础学习系列文章目录前言一、使用1.1 安装1.2 配置 二、功能总结 前言 corsheaders 是一个 Django 第三方应用&#xff0c;用于处理跨域资源共享 (CORS)。CORS 是一种机制&#x…

【简单好抄保姆级教学】javascript调用本地exe程序(谷歌,edge,百度,主流浏览器都可以使用....)

javascript调用本地exe程序 详细操作步骤结果 详细操作步骤 在本地创建一个txt文件依次输入 1.指明所使用注册表编程器版本 Windows Registry Editor Version 5.00这是脚本的第一行&#xff0c;指明了所使用的注册表编辑器版本。这是必需的&#xff0c;以确保脚本能够被正确解…

Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破!

01. 概览 我们很高兴为大家带来 Milvus 2.5 最新版本的介绍。 在 Milvus 2.5 里&#xff0c;最重要的一个更新是我们带来了“全新”的全文检索能力&#xff0c;之所以说“全新”主要是基于以下两点&#xff1a; 第一&#xff0c;对于全文检索基于的 BM25 算法&#xff0c;我们采…

【数据分析】布朗运动(维纳过程)

文章目录 一、概述二、数学布朗运动2.1 数学定义2.2 布朗运动的数学模型2.21 标准布朗运动2.22 布朗运动的路径2.23 布朗运动的方程 三、布朗运动在金融学中的应用四、数学构造&#xff08;以傅里叶级数为例&#xff09;4.1 傅里叶级数的基本思想4.2 构造布朗运动 一、概述 布…

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway)

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway) 一、服务网关 1.1 什么是网关 在微服务架构中&#xff0c;服务网关是一个至关重要的组件。它作为系统的入口&#xff0c;负责接收客户端的请求&#xff0c;并将这些请求路由到相应的后端服务…

即时通讯| IM+RTC在AI技术加持下的社交体验

即时通讯作为互联网的重要应用之一&#xff0c;见证了中国互联网30年发展的辉煌历程。 它从最初的文字交流&#xff0c;发展到如今的语音、视频通话&#xff0c;甚至是虚拟现实社交&#xff0c;已经渗透到生活的社交、娱乐、商务等方方面面&#xff0c;成为现代社会不可或缺的一…

【docker】docker常用命令汇总

1.Docker 常用命令总结表格 Docker 环境信息命令 命令作用docker version查看 Docker 客户端和服务端的版本信息docker info查看 Docker 系统的详细信息&#xff0c;包括存储驱动、内核版本等docker inspect <name or id>获取容器或镜像的详细配置信息docker system df…

【Java基础入门篇】一、变量、数据类型和运算符

Java基础入门篇 一、变量、数据类型和运算符 1.1 变量 计算机中的数据表示方式是&#xff1a;“二进制(0/1)”&#xff0c;但是同时也可以兼容其他进制&#xff0c;例如八进制、十进制、十六进制等。 Java变量的本质是&#xff1a;存储在固定空间的内容&#xff0c;变量名是…

鸿蒙技术分享:Navigation页面管理-鸿蒙@fw/router框架源码解析(二)

theme: smartblue 本文是系列文章&#xff0c;其他文章见&#xff1a;鸿蒙fw/router框架源码解析&#xff08;一&#xff09;-Router页面管理 鸿蒙fw/router框架源码解析 介绍 fw/router是在HarmonyOS鸿蒙系统中开发应用所使用的开源模块化路由框架。该路由框架基于模块化开…

【博主推荐】C#的winfrom应用中datagridview常见问题及解决方案汇总

文章目录 1.datagridview绘制出现鼠标悬浮数据变空白2.datagridview在每列前动态添加序号2.1 加载数据集完成后绘制序号2.2 RowPostPaint事件绘制 3.datagridview改变行样式4.datagridview后台修改指定列数据5.datagridview固定某个列宽6.datagridview某个列的显示隐藏7.datagr…

宠物领养平台构建:SpringBoot技术路线图

摘 要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领养…

使用经典的Java,还是拥抱新兴的Rust?

在当代互联网时代的企业级开发中&#xff0c;技术栈的选择往往牵动着每个团队的神经。随着Rust语言的崛起&#xff0c;许多开发团队开始重新思考&#xff1a;是继续坚持使用经典的Java&#xff0c;还是拥抱新兴的Rust&#xff1f;这个问题背后&#xff0c;折射出的是对技术演进…

springboot学习-jdbc,jdbc-client,spring-data-jdbc

晚上又看了Dan Vega的视频&#xff0c;讲解了jdbc在spring 的发展史。 jdbc: sql语句&#xff0c;手工梳理result&#xff0c;并循环。最原始的JAVA API&#xff0c;从1998年JAVA1.0就有了。jdbc template: sql语句&#xff0c;手工处理result ,不用循环了。--从spring诞生就有…

卸载snap docker一直卡住:Save data of snap “docker“ in automatic snapshot set #3

在卸载 Snap 安装的 Docker 时卡住&#xff0c;通常是因为 Snap 在执行卸载时会先尝试保存一些快照&#xff08;自动或手动创建的&#xff09;&#xff0c;并且该过程可能因某些原因而卡住。为了解决这个问题&#xff0c;你可以按照以下步骤强制删除 Snap 安装的 Docker&#x…