问题背景

在项目中需要配置 QQ 邮箱的 SMTP 来发送邮件。查资料时发现 QQ 邮箱的 SMTP 服务器有两个端口:465587。当时想当然地以为这两个端口随便选一个都行,结果踩了不少坑。

核心结论

这两个端口不能随意使用,它们对应两种完全不同的加密方式:

  • 465 端口 + SSL(隐式 TLS)secure: true,连接建立后立刻进行 TLS 握手
  • 587 端口 + STARTTLS(显式 TLS)secure: false,先明文 EHLO,再通过 STARTTLS 升级为加密连接

两种端口到底有什么区别

特性 465 (SSL) 587 (STARTTLS)
加密方式 隐式 TLS 显式 TLS
连接方式 建立连接立刻 TLS 握手 先明文 EHLO,再 STARTTLS 升级
secure 参数 true false
适用场景 传统客户端、部分老系统 现代邮件客户端、标准 SMTP 提交

配置示例

465 端口(SSL)

const transporter = nodemailer.createTransport({
  host: 'smtp.qq.com',
  port: 465,
  secure: true, // 465 端口必须为 true
  auth: {
    user: '你的QQ邮箱@qq.com',
    pass: '授权码',
  },
});

587 端口(STARTTLS)

const transporter = nodemailer.createTransport({
  host: 'smtp.qq.com',
  port: 587,
  secure: false, // 587 端口必须为 false
  auth: {
    user: '你的QQ邮箱@qq.com',
    pass: '授权码',
  },
});

踩坑点总结

  1. 端口和 secure 必须配套:465 配 secure: true,587 配 secure: false。写反了就会握手失败或连接被拒。

  2. 587 端口:当 secure: false 时,客户端会先以明文发送 EHLO,然后通过 STARTTLS 升级加密。如果服务器不支持 STARTTLS,连接会失败。

  3. 465 端口:连接一建立就立刻 TLS 握手,不需要 STARTTLS 协商过程。

  4. QQ 邮箱注意:配置 SMTP 时密码不能直接用邮箱密码,要用邮箱网页设置里生成的授权码

常见报错排查

  • Connection closedGreeting never received:多半是端口和 secure 不匹配,检查是否 465 配了 false 或 587 配了 true
  • 认证失败:检查是否用了授权码而不是邮箱密码。
  • 超时:确认服务器是否开放了对应端口,以及是否在 QQ 邮箱设置里开启了 SMTP 服务。

小结

记住一句话:465 配 SSL,587 配 STARTTLS,secure 参数跟着端口走。配置前先确认目标邮箱服务器支持哪种加密方式,再选择对应端口,就能避免大部分坑。