之前不知道怎么发邮件的功能,记录一下
总体的功能实现是:要改密码,绑定/解绑邮箱的时候,我们就会给邮箱发信息确认。
==config.go==
1 2 3 4 5 email: address: xxxxxxx smtpHost: smtp.qq.com smtpEmail: xxxx@qq.com smtpPass: xxxxx
==email.go==
发送的实现其实并不是服务器内部决定的,而是通过QQ邮箱,相当于是将QQ邮箱当作代理,让QQ邮箱来帮我们发送邮件。
那么想要让QQ邮箱为我们发送代理,我们就需要QQ邮箱的权限,因此我们要想取开通一下权限
设置我们发送的邮箱类型(还可以选择其他邮箱)smtpHost
去网页里面开启权限,获得smtpPass ,这个相当于权限的钥匙
我们要确认发送方的地址 SmtpEmailFrom
我们还要确认发送方的 姓名 subject
我们还需要设置一下给谁发邮箱,一般来说这个谁 需要 用户自己输入或者数据库读取 To
开始写信封,确认一下信的内容形式
发送即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package emailimport ( conf "gin-mall/conf/sql" "gin-mall/consts" "gopkg.in/mail.v2" ) type EmailSender struct { SmtpHost string `json:"smtp_host"` SmtpEmailFrom string `json:"smtp_email_from"` SmtpPass string `json:"smtp_pass"` } func NewEmailSender () *EmailSender { eConfig := conf.Config.Email return &EmailSender{ SmtpHost: eConfig.SmtpHost, SmtpEmailFrom: eConfig.SmtpEmail, SmtpPass: eConfig.SmtpPass, } } func (s *EmailSender) Send(data, emailTo, subject string ) error { m := mail.NewMessage() m.SetHeader("From" , s.SmtpEmailFrom) m.SetHeader("To" , emailTo) m.SetHeader("Subject" , subject) m.SetBody("text/html" , data) d := mail.NewDialer(s.SmtpHost, consts.SmtpEmailPort, s.SmtpEmailFrom, s.SmtpPass) d.StartTLSPolicy = mail.MandatoryStartTLS if err := d.DialAndSend(m); err != nil { return err } return nil }
为了确认安全 ,所以我们还要再加一个token
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 func GenerateEmailToken (uid uint , email, password string , operationType uint ) (token string , err error ) { claims := EmailClaims{ ID: uid, Email: email, Password: password, OperationType: operationType, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(10 * time.Minute).Unix(), Issuer: "cmall" , }, } token, err = jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte (jwtSecret)) return token, err } func ParseEmailToken (token string ) (*EmailClaims, error ) { tokenClaims, err := jwt.ParseWithClaims(token, &EmailClaims{}, func (token *jwt.Token) (interface {}, error ) { return []byte (jwtSecret), nil }) if tokenClaims != nil { if claims, ok := tokenClaims.Claims.(*EmailClaims); ok && tokenClaims.Valid { return claims, nil } } return nil , err }
最后业务处理
发送邮件
收到邮件解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 func (s *UserSrv) SendEmail(ctx context.Context, req *types.SendEmailServiceReq) (resp interface {}, err error ) { u, err := ctl.GetUserInfo(ctx) if err != nil { log.LogrusObj.Error(err) return } var address string token, err := jwt.GenerateEmailToken(u.Id, req.Email, req.Password, req.OperationType) if err != nil { log.LogrusObj.Error(err) return nil , err } sender := email.NewEmailSender() address = conf.Config.Email.ValidEmail + token mailText := fmt.Sprintf(consts.EmailOperationMap[req.OperationType], address) if err = sender.Send(mailText, req.Email, consts.EmailSubject); err != nil { log.LogrusObj.Error(err) return } return } func (s *UserSrv) ValidEmail(ctx context.Context, req *types.ValidEmailReq) (resp interface {}, err error ) { var uId uint var eml string var pass string var OperationType uint if req.Token == "" { err = errors.New("token不存在" ) return } claims, err := jwt.ParseEmailToken(req.Token) if err != nil { return } else { uId = claims.ID eml = claims.Email pass = claims.Password OperationType = claims.OperationType } userDao := dao.NewUserDao(ctx) user, err := userDao.GetUserById(uId) if err != nil { return } switch OperationType { case consts.EmailOperationBinding: user.Email = eml case consts.EmailOperationNoBinding: user.Email = "" case consts.EmailOperationUpdatePassword: err = user.SetPassword(pass) if err != nil { log.LogrusObj.Error("密码加密错误" ) return } default : return nil , errors.New("操作类型错误" ) } err = userDao.UpdateUserById(uId, user) if err != nil { log.LogrusObj.Error(err) return } resp = &types.UserInfoResp{ ID: user.ID, UserName: user.UserName, NickName: user.NickName, Email: user.Email, Status: user.Status, Avatar: user.AvatarURL(), CreateAt: user.CreatedAt.Unix(), } return }
总结 这个东西,写了一遍就知道怎么写了
不过还是要看文档…………..