Go的net/smtp包仅支持PLAIN/LOGIN认证且不支持OAuth2,无法直接用于Gmail等现代邮箱;发送HTML或附件需手动构造MIME,易出错,推荐使用gomail等第三方库。

Go 的 net/smtp 包能发邮件,但只支持 PLAIN 和 LOGIN 认证,不支持 OAuth2;它也不处理 MIME 编码、附件或 HTML 正文——这些得自己拼或用第三方库。
为什么直接调用 smtp.SendMail 常失败
多数现代邮箱(Gmail、Outlook、阿里云邮箱)已禁用「密码直连 SMTP」,要求开启应用专用密码或使用 OAuth2。而 net/smtp 根本不支持 OAuth2 流程,所以填对账号密码也大概率报错 535 5.7.8 Username and Password not accepted。
常见误操作:
- 用主账号密码直连 Gmail —— 必失败(需开「两步验证 + 应用专用密码」)
- 忽略 TLS/SSL 端口差异:Gmail 是
smtp.gmail.com:587(STARTTLS)或:465(SSL),填错端口会卡在连接阶段 - 没设置
From和To邮箱在邮件头里,导致被拒收或进垃圾箱
发送纯文本邮件的最小可行代码
以下示例仅适用于已开通「应用专用密码」的 Gmail(其他服务商类似,注意主机、端口、认证方式):
package main
import (
"fmt"
"net/smtp"
)
func main() {
auth := smtp.PlainAuth("", "your@gmail.com", "your-app-password", "smtp.gmail.com")
msg := []byte("To: recipient@example.com\r\n" +
"From: your@gmail.com\r\n" +
"Subject: Hello\r\n" +
"\r\n" +
"This is plain text body.\r\n")
err := smtp.SendMail("smtp.gmail.com:587", auth, "your@gmail.com", []string{"recipient@example.com"}, msg)
if err != nil {
fmt.Println("Send error:", err)
return
}
fmt.Println("Sent!")
}
关键点:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
smtp.PlainAuth第一个空字符串是「身份标识」,Gmail 可留空;第三个参数必须是应用专用密码,不是 Gmail 登录密码 - 邮件正文前必须有两个
\r\n(空行),否则From/Subject会被当成正文 -
msg是原始字节流,不自动编码,中文需手动转 UTF-8 并加Content-Type: text/plain; charset=utf-8头
添加 HTML 正文和简单附件需要自己构造 MIME
net/smtp 不提供 MIME 封装能力,你要手动拼接边界(boundary)、Base64 编码附件、设置正确的 Content-Type 和 Content-Transfer-Encoding。稍有错位(比如多一个换行、少一个 --)就会导致收件方无法解析。
例如添加 HTML 正文,必须写成:
<pre class="brush:php;toolbar:false;">... "Content-Type: multipart/alternative; boundary=\"boundary123\"\r\n" + "\r\n" + "--boundary123\r\n" + "Content-Type: text/plain; charset=utf-8\r\n" + "\r\n" + "Plain version\r\n" + "--boundary123\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "\r\n" + "<b>HTML</b> version\r\n" + "--boundary123--\r\n"
真实项目中几乎没人手写 MIME —— 容易出错且难以维护。更稳妥的做法是用 gopkg.in/gomail.v2 或 <code>github.com/sethgrid/pester 这类封装好的库,它们内部处理了编码、边界、附件流式读取等细节。
真正麻烦的从来不是「怎么发」,而是「怎么让邮件不被当垃圾邮件」:SPF/DKIM/DMARC 配置、发信 IP 信誉、正文链接比例、退订机制——这些 net/smtp 一概不管,得靠基础设施配合。

















