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()
}

 

posted @ 2019-07-01 10:08  温斌  阅读(282)  评论(0编辑  收藏