错误消息Error: tls: first record does not look like a TLS handshake
告诉您问题出在哪里:-)。如果尝试连接到服务器,您将看到(与任何SMTP服务器一样)它使用纯文本:
telnet smtp.office365.com 587
Trying 2603:1026:c0b:10::2...
Connected to zrh-efz.ms-acdc.office.com.
Escape character is '^]'.
220 ZRAP278CA0003.outlook.office365.com Microsoft ESMTP MAIL Service ready at Mon,11 Nov 2019 17:13:50 +0000
...
您需要使用STARTTLS
命令,请参见https://en.wikipedia.org/wiki/Opportunistic_TLS(以及该Wiki页面所指向的RFC)。
在Go中,它是https://golang.org/pkg/net/smtp/#Client.StartTLS。
在您的代码中,我注意到了
tlsconfig := &tls.Config{
InsecureSkipVerify: true,<== REMOVE THIS
ServerName: host,}
请删除InsecureSkipVerify
,顾名思义,它是不安全的,与您面临的错误无关。
,
- Outlook.com自2017年8月起不再支持AUTH PLAIN身份验证。
https://support.microsoft.com/en-us/office/outlook-com-no-longer-supports-auth-plain-authentication-07f7d5e9-1697-465f-84d2-4513d4ff0145?ui=en-us&rs=en-us&ad=us
- 使用AUTH LOGIN
以下代码实现了AUTH LOGIN
type loginAuth struct {
username,password string
}
func LoginAuth(username,password string) smtp.Auth {
return &loginAuth{username,password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string,[]byte,error) {
return "LOGIN",[]byte(a.username),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 from server")
}
}
return nil,nil
}
- 删除“ InsecureSkipVerify:true”
tlsconfig := &tls.Config {
ServerName: host,}
- 请勿使用tsl.Dial(),而应使用net.Dial()
conn,err := net.Dial("tcp","smtp.office365.com:587")
if err != nil {
return err
}
- 在smtp.NewClient()之后调用StartTLS()
c,err := smtp.NewClient(conn,host)
if err != nil {
return err
}
if err = c.StartTLS(tlsconfig); err != nil {
return err
}
- 使用AUTH LOGIN
auth := LoginAuth(fromAddress,password)
if err = c.Auth(auth); err != nil {
return err
}
,
以下与我合作很好:
package main
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"net"
"net/smtp"
"text/template"
)
type loginAuth struct {
username,password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string,nil
}
func (a *loginAuth) Next(fromServer []byte,nil
}
func main() {
// Sender data.
from := "O365 logging name"
password := "O365 logging pasword"
// Receiver email address.
to := []string{
"receiver email",}
// smtp server configuration.
smtpHost := "smtp.office365.com"
smtpPort := "587"
conn,"smtp.office365.com:587")
if err != nil {
println(err)
}
c,smtpHost)
if err != nil {
println(err)
}
tlsconfig := &tls.Config{
ServerName: smtpHost,}
if err = c.StartTLS(tlsconfig); err != nil {
println(err)
}
auth := LoginAuth(from,password)
if err = c.Auth(auth); err != nil {
println(err)
}
t,_ := template.ParseFiles("template.html")
var body bytes.Buffer
mimeHeaders := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
body.Write([]byte(fmt.Sprintf("Subject: This is a test subject \n%s\n\n",mimeHeaders)))
t.Execute(&body,struct {
Name string
Message string
}{
Name: "Hasan Yousef",Message: "This is a test message in a HTML template",})
// Sending email.
err = smtp.SendMail(smtpHost+":"+smtpPort,auth,from,to,body.Bytes())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Email Sent!")
}
使用以下模板作为奖励:)
<!-- template.html -->
<!DOCTYPE html>
<html>
<body>
<h3>Name:</h3><span>{{.Name}}</span><br/><br/>
<h3>Email:</h3><span>{{.Message}}</span><br/>
</body>
</html>
,
所以问题全在授权上。首先要求我在客户端上使用StartTLS方法,还要求我编写一个函数和方法来支持LOGIN,而标准Go库则不支持(出于某种原因)
请参阅main()上方的函数和结构
这是带有帮助程序功能的完整代码,现在可以通过我的O365帐户成功发送电子邮件:
package main
import (
"fmt"
"net"
"errors"
mail "net/mail"
smtp "net/smtp"
)
type loginAuth struct {
username,[]byte{},errors.New("Unknown fromServer")
}
}
return nil,nil
}
func main() {
from := mail.Address{"","example@example.com"}
to := mail.Address{"","example@example.com"}
subject := "My test subject"
body := "Test email body"
headers := make(map[string]string)
headers["From"] = from.String()
headers["To"] = to.String()
headers["Subject"] = subject
message := ""
for k,v := range headers {
message += fmt.Sprintf("%s: %s\r\n",k,v)
}
message += "\r\n" + body
tlsconfig := &tls.Config{
ServerName: host,}
conn,err := tls.Dial("tcp","smtp.office365.com:587",tlsconfig)
if err != nil {
fmt.Println("tls.Dial Error: ",err)
}
c,host)
if err != nil {
fmt.Println("smtp.NewClient Error: ",err)
}
if err = c.Auth(LoginAuth("example@example.com","password")); err != nil {
fmt.Println("c.Auth Error: ",err)
return
}
if err = c.Mail(from.Address); err != nil {
fmt.Println("c.Mail Error: ",err)
}
if err = c.Rcpt(to.Address); err != nil {
fmt.Println("c.Rcpt Error: ",err)
}
w,err := c.Data()
if err != nil {
fmt.Println("c.Data Error: ",err)
}
_,err = w.Write([]byte(message))
if err != nil {
fmt.Println("Error: ",err)
}
err = w.Close()
if err != nil {
fmt.Println("reader Error: ",err)
}
c.Quit()
}
本文链接:https://www.f2er.com/3122917.html