Go发送Email
使用Go发送邮件,目前官网GO 1.12的版本的文档中,包 "net/smtp" 仅支持支持两种SMTP的认证方式。CRAM-MD5和PLAIN 认证方式。
CRAM-MD5 是基于Keyed-MD5的认证方式
PLAIN 是一种明文的验证方式
我们公司使用的邮件服务器SMTP支持两种认证方式:NTLM 和 LOGIN
查看邮件服务器支持SMTP的认证方式的方法:

在这种情况下:
1、直接使用Go官网"net/smtp"的认证方式发送邮件回报错
报错:x509: certificate signed by unknown authority
理解: 这个是GO的客户端对服务器传过来数字证书进行校验,可以进行关闭,不进行校验。
代码:
if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: c.serverName, InsecureSkipVerify: true}
if testHookStartTLS != nil {
testHookStartTLS(config)
}
if err = c.StartTLS(config); err != nil {
return err
}
}
报错:504 5.7.4 Unrecognized authentication type
理解:GO官网包 "net/smtp" 仅支持 CRAM-MD5和PLAIN 而我们公司邮件服务器支持认证方式 NTLM 和 LOGIN
2、支持SMTP的LOGIN认证方式的代码
type LoginAuth struct {
username string
password string
}
func NewLoginAuth(username, password string) smtp.Auth {
return &LoginAuth{username, password}
}
func (a *LoginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
return "LOGIN", []byte{}, nil
}
func (a *LoginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case "Username:":
return []byte(a.username), nil
case "Password:":
return []byte(a.password), nil
default:
return nil, errors.New("Unknown fromServer")
}
}
return nil, nil
}
func SendMail(addr string, a smtp.Auth, subject string, from string, to []string, msg []byte) error {
c, err := smtp.Dial(addr)
host, _, _ := net.SplitHostPort(addr)
if err != nil {
fmt.Println("call dial")
return err
}
defer c.Close()
if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: host, InsecureSkipVerify: true}
if err = c.StartTLS(config); err != nil {
fmt.Println("call start tls")
return err
}
}
if a != nil {
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(a); err != nil {
fmt.Println("check auth with err:", err)
return err
}
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
header := make(map[string]string)
header["Subject"] = subject
header["MIME-Version"] = "1.0"
header["Content-Type"] = "text/plain; charset=\"utf-8\""
header["Content-Transfer-Encoding"] = "base64"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + base64.StdEncoding.EncodeToString(msg)
_, err = w.Write([]byte(message))
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}
Go发送Email的更多相关文章
- java发送email
package com.assess.util; import java.io.File; import java.util.ArrayList; import java.util.List; imp ...
- Spring 发送 Email
本文转自:http://zl198751.iteye.com/blog/757617 看到了本文,收获颇丰,感谢之至! 首先介绍下Email的发送流程: 需要选中smtp邮件服务器,Yahoo不提供免 ...
- 使用PHP发送email进行账号激活或者密码修改操作
使用PHPMailer编写发送邮件 PHPMailer需PHP的socket扩展支持,而PHPMailer链接qq域名邮箱时需要ssl加密方式(qq邮箱最近做了限制,新开域名邮箱不再允许通过smtp协 ...
- 使用python原生的方法实现发送email
使用python原生的方法实现发送email import smtplib from email.mime.text import MIMEText from email.mime.multipart ...
- C#发送Email邮件(实例:QQ邮箱和Gmail邮箱)
下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需要引用: using System.Net.Mail; using System.Text; using System.Net; ...
- 【WinForm】C# 发送Email
发送Email 的条件 1.SmtpClient SMTP 协议 即 Host 处理事务的主机或IP地址 //smtp.163.com UseDefaultCredentia ...
- [转]C#发送Email邮件 (实例:QQ邮箱和Gmail邮箱)
下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需要引用:using System.Net.Mail;using System.Text;using System.Net; 程序 ...
- asp.net发送E-mail
发送电子邮件也是项目开发当中经常用到的功能,这里我整理了一个发送电子邮件(带附件,支持多用户发送,主送.抄送)的类库,供大家参考. 先上两个实体类,用于封装成Mail对象. /// <summa ...
- 使用spring 并加载模板发送Email 发邮件 java 模板
以下例子是使用spring发送email,然后加载到固定的模板,挺好的,大家可以试试 需要使用到spring-context 包 和 com.springsource.org.apache.veloc ...
- [Python] 发送email的几种方式
python发送email还是比較简单的,能够通过登录邮件服务来发送,linux下也能够使用调用sendmail命令来发送,还能够使用本地或者是远程的smtp服务来发送邮件,无论是单个,群发,还是抄送 ...
随机推荐
- (day47)jQuery
目录 一.初识jQuery (一)jQuery介绍 (二)版本介绍 (三)jQuery对象 (四)相关网站 (五)基础语法 二.查找标签 (一)基本选择器 (1)id选择器 (2)标签选择器 (3)c ...
- LeetCode 53. Maximum Subarray最大子序和 (C++)
题目: Given an integer array nums, find the contiguous subarray (containing at least one number) which ...
- leetcode209. 长度最小的子数组
双指针滑动窗口解法,时间复杂度O(N). 滑动窗口,想象一下,在一个坐标上存在两个指针begin 和i ,begin 代表滑窗的左边框,i代表滑窗的右边框.两者通过分别向右滑动,前者能使窗口之间的和减 ...
- [LeetCode] 880. Decoded String at Index 在位置坐标处解码字符串
An encoded string S is given. To find and write the decoded string to a tape, the encoded string is ...
- [LeetCode] 102. Binary Tree Level Order Traversal 二叉树层序遍历
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- 2019 SDN上机第1次作业
一.安装轻量级网络仿真工具Mininet 克隆github上的Mininet源 git clone https://github.com/mininet/mininet 选择默认全部安装 cd min ...
- Unity和Jenkins真是绝配,将打包彻底一键化!
说起打包,我们的QA简直是要抓狂,这个确实我也很同情他们.项目最开始打包是另一个同事做的,打包步骤是有些繁琐,但是项目上线后,不敢轻易动啊!每次他们打包总要跟我抱怨,国内版本打包步骤要10多步还能忍, ...
- JOSH是中国的“MicroEJ”~
很多人不了解JOSH,我们推荐大家去看看MicroEJ,我们是中国版的MICROEJ,下面的文章翻译自MICROEJ的官网,让大家直观的了解~ MICROEJ被定位为可连接对象的ANDROID™的小兄 ...
- OPTIONS预检请求
OPTIONS预检请求 背景:像后台发送一个post请求,出错,错误代码403(权限验证未通过),查看请求方法变成OPTIONS.检查请求头得知,当前请求token未带上,问题,为什么post请求变成 ...
- Luogu P2727 【01串 Stringsobits】
看到题解里好像都是用$DP$解决的,本着禁止DP的原则,我来提供一发纯数学其实和DP本质相同的题解,前两天刚反演题,脑子炸了,本来说换换脑子,结果还是数学 首先受进制思想启发,我们不妨按位考虑,考虑这 ...