使用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的更多相关文章

  1. java发送email

    package com.assess.util; import java.io.File; import java.util.ArrayList; import java.util.List; imp ...

  2. Spring 发送 Email

    本文转自:http://zl198751.iteye.com/blog/757617 看到了本文,收获颇丰,感谢之至! 首先介绍下Email的发送流程: 需要选中smtp邮件服务器,Yahoo不提供免 ...

  3. 使用PHP发送email进行账号激活或者密码修改操作

    使用PHPMailer编写发送邮件 PHPMailer需PHP的socket扩展支持,而PHPMailer链接qq域名邮箱时需要ssl加密方式(qq邮箱最近做了限制,新开域名邮箱不再允许通过smtp协 ...

  4. 使用python原生的方法实现发送email

    使用python原生的方法实现发送email import smtplib from email.mime.text import MIMEText from email.mime.multipart ...

  5. C#发送Email邮件(实例:QQ邮箱和Gmail邮箱)

    下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需要引用: using System.Net.Mail; using System.Text; using System.Net; ...

  6. 【WinForm】C# 发送Email

    发送Email  的条件 1.SmtpClient SMTP 协议    即 Host 处理事务的主机或IP地址     //smtp.163.com      UseDefaultCredentia ...

  7. [转]C#发送Email邮件 (实例:QQ邮箱和Gmail邮箱)

    下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需要引用:using System.Net.Mail;using System.Text;using System.Net; 程序 ...

  8. asp.net发送E-mail

    发送电子邮件也是项目开发当中经常用到的功能,这里我整理了一个发送电子邮件(带附件,支持多用户发送,主送.抄送)的类库,供大家参考. 先上两个实体类,用于封装成Mail对象. /// <summa ...

  9. 使用spring 并加载模板发送Email 发邮件 java 模板

    以下例子是使用spring发送email,然后加载到固定的模板,挺好的,大家可以试试 需要使用到spring-context 包 和 com.springsource.org.apache.veloc ...

  10. [Python] 发送email的几种方式

    python发送email还是比較简单的,能够通过登录邮件服务来发送,linux下也能够使用调用sendmail命令来发送,还能够使用本地或者是远程的smtp服务来发送邮件,无论是单个,群发,还是抄送 ...

随机推荐

  1. JQuery:

    一 jQuery是什么? <1> jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. <2>jQuery是继 ...

  2. String的拼接

    1.直接定义字符串变量的时候赋值,如果表达式右边只有字符串常量,那么就是把变量存放在常量池里面. 2.new出来的字符串是存放在堆里面. 3.对字符串进行拼接操作,也就是做"+"运 ...

  3. python的可变类型和不可变类型

    Python有六种数据类型:数字类型.字符串类型.列表类型.元组类型.字典类型和集合类型 其中不可变类型包括三种:数字类型.字符串类型和元组类型 剩余三种为可变类型:列表类型.字典类型和集合类型 可变 ...

  4. 复杂模拟 | 1014 模拟K个同时到来的人在N个窗口,每个窗口只能站M个人的银行排队

    这题我以为还是之前银行排队的思路,但是做着做着就做不下去了了.看了答案我才理解到底是什么个思路. 是这样的:不同于之前排队的题,这里的K个人是同时到来的.所以首先应该让K个人的前N*M(也就是黄线内的 ...

  5. [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  6. UDF——读取文件作为边界条件(类似profile的效果)

    本文编译工具:VC++ UDF Studio 该插件可以直接在Visual Studio中一键编译.加载.调试UDF源码,极大提高编写排错效率,且支持C++,MFC,Windows API和第三方库, ...

  7. canal

    https://github.com/alibaba/canal/wiki/QuickStart https://github.com/alibaba/canal/releases/download/ ...

  8. Qt Quick 多媒体 - 播放音乐和视频

    MediaPlayer 是 QML 提供的核心多媒体类,可以播放音频.视频.要使用 MediaPlayer,需要引入 QtMultimedia 模块,在 QML 文档的开始加入 "impor ...

  9. Loj #3102. 「JSOI2019」神经网络

    Loj #3102. 「JSOI2019」神经网络 题目背景 火星探险队发现,火星人的思维方式与人类非常不同,是因为他们拥有与人类很不一样的神经网络结构.为了更好地理解火星人的行为模式,JYY 对小镇 ...

  10. Using MS Soap toolkit to generate web services .md

    Different SOAP encoding styles - RPC, RPC-literal, and document-literal SOAP Remote Procedure Call(R ...