QQ邮箱授权码必须关闭「独立密码」才能生效,否则SMTP认证静默失败;配置需严格匹配JSON字段名与类型,To必须为字符串切片,From须与username一致,且务必检查err并记录。

QQ邮箱授权码必须关掉「独立密码」才能用
很多开发者填对了账号、密码、端口,Send() 却静默失败或返回 auth: failed to authenticate,根本原因就是 QQ 邮箱开了「独立密码」——它会直接让授权码失效。哪怕你刚生成了 16 位授权码,只要独立密码处于开启状态,SMTP 认证就通不过。
操作路径:登录 QQ 邮箱网页 → 设置 → 账户 → 找到「独立密码」→ 点击「关闭」→ 返回「POP3/IMAP/SMTP/Exchange」页面 → 重新开启 SMTP 并完成密保验证 → 获取新授权码
- 授权码只显示一次,复制后立刻保存
- 改过 QQ 密码,授权码也会立即过期
- 企业微信或第三方邮件客户端同样受此限制,不关独立密码,所有 SMTP 请求都会被静默拒绝
JSON 配置字段名和类型必须严格匹配
utils.NewEMail() 接收一个 JSON 字符串,但不校验字段合法性。拼错字段(比如写成 "passwd"、"smtp_host")或类型错误(如把 port 写成字符串 "587"),会导致连接被拒,错误提示往往只有泛化的 connection refused 或直接 panic。
- 必需字段仅四个,且类型固定:
username(完整邮箱地址,字符串)、password(16 位纯字母数字授权码,非登录密码)、host(字符串,如"smtp.qq.com")、port(整数,推荐587;避免用465,Beegoutils中 SSL 模式支持不稳定) - 正确示例:
{"username":"test@qq.com","password":"abcd1234efgh5678","host":"smtp.qq.com","port":587} - 常见错误:
"port": "587"(字符串)、"user"代替"username"、"smtp_port"代替"port"
To 必须是 []string,From 必须与 username 完全一致
emailConn.To = "user@example.com" 看似自然,但会 panic —— Beego 强制要求 To 是切片类型。哪怕只发给一个人,也得写成 []string{"user@example.com"}。
-
From是字符串,但必须和配置里的username完全一致,否则 QQ 邮箱网关会直接拒收(尤其在企业环境或反垃圾策略较严时) - 正文至少填
Text或HTML其中一个,都为空会返回empty body错误 -
emailConn.From不设或设错,邮件可能进垃圾箱甚至被拦截
发送前务必检查 err 并隔离日志输出
Beego 的 beego.BeeLogger 是全局单例。真实项目里邮件和短信通知常并存,但共用 BeeLogger 会导致日志混杂、故障难定位。
- 发送后必须显式检查
err,用beego.Error()或独立 logger 输出,否则失败无声无息 - 邮件日志建议单独初始化一个
logs.Logger实例,避免和业务日志、HTTP 日志耦合 - 别依赖
fmt.Println()调试,生产环境看不到终端输出;错误信息里要包含原始err.Error(),而不是只打"send failed"
最易忽略的其实是授权码生命周期和字段类型校验——它们不会报编译错误,也不触发 panic,而是让整个流程在 Send() 时无声失败。每次换环境、升级 Beego 版本或重置 QQ 密码后,都要重新核对这两点。


















