init
This commit is contained in:
139
Backend/internal/service/email.go
Normal file
139
Backend/internal/service/email.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/smtp"
|
||||
"time"
|
||||
|
||||
"github.com/jordan-wright/email"
|
||||
"github.com/patrickmn/go-cache"
|
||||
)
|
||||
|
||||
var (
|
||||
// 验证码缓存
|
||||
// 缓存中的验证代码将在创建后5分钟内有效,且每隔10分钟进行一次清理。
|
||||
verificationCodeCache = cache.New(5*time.Minute, 10*time.Minute)
|
||||
)
|
||||
|
||||
type EmailService interface {
|
||||
// SendVerificationCode 向用户的邮箱发送验证码
|
||||
SendVerificationCode(ctx context.Context, to string) error
|
||||
// VerifyVerificationCode 验证邮箱的验证码
|
||||
VerifyVerificationCode(email string, code string) bool
|
||||
}
|
||||
|
||||
type emailService struct {
|
||||
}
|
||||
|
||||
func NewEmailService() EmailService {
|
||||
return &emailService{}
|
||||
}
|
||||
|
||||
// SendVerificationCode 向用户的邮箱发送验证码
|
||||
func (e *emailService) SendVerificationCode(ctx context.Context, to string) error {
|
||||
code := generateVerificationCode()
|
||||
|
||||
err := e.sendVerificationCode(to, code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将验证码存储在缓存中以供后续验证
|
||||
verificationCodeCache.Set(to, code, cache.DefaultExpiration)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendVerificationCode 发送验证代码到指定的邮箱。
|
||||
// 参数 to: 邮件接收人的邮箱地址。
|
||||
// 参数 code: 需要发送的验证代码。
|
||||
// 返回值 error: 发送过程中遇到的任何错误。
|
||||
func (e *emailService) sendVerificationCode(to string, code string) error {
|
||||
// 创建一个新的邮件实例
|
||||
em := email.NewEmail()
|
||||
em.From = "3149026837@qq.com"
|
||||
em.To = []string{to}
|
||||
em.Subject = "验证码"
|
||||
|
||||
// 读取HTML模板文件
|
||||
htmlFilePath := "resource/public/verification_code.html"
|
||||
if tmplContent, err := ioutil.ReadFile(htmlFilePath); err == nil {
|
||||
// 成功读取模板文件,使用模板
|
||||
tmpl, err := template.New("verification").Parse(string(tmplContent))
|
||||
if err == nil {
|
||||
var buf bytes.Buffer
|
||||
data := map[string]string{"Code": code}
|
||||
if err := tmpl.Execute(&buf, data); err == nil {
|
||||
em.HTML = buf.Bytes()
|
||||
} else {
|
||||
// 模板执行失败,使用默认内容
|
||||
em.HTML = []byte(fmt.Sprintf(`
|
||||
<h1>验证码</h1>
|
||||
<p>您的验证码是: <strong>%s</strong></p>
|
||||
<p>此验证码将在5分钟后过期。</p>
|
||||
`, code))
|
||||
}
|
||||
} else {
|
||||
// 模板解析失败,使用默认内容
|
||||
em.HTML = []byte(fmt.Sprintf(`
|
||||
<h1>验证码</h1>
|
||||
<p>您的验证码是: <strong>%s</strong></p>
|
||||
<p>此验证码将在5分钟后过期。</p>
|
||||
`, code))
|
||||
}
|
||||
} else {
|
||||
// 读取模板文件失败,使用默认内容
|
||||
em.HTML = []byte(fmt.Sprintf(`
|
||||
<h1>验证码</h1>
|
||||
<p>您的验证码是: <strong>%s</strong></p>
|
||||
<p>此验证码将在5分钟后过期。</p>
|
||||
`, code))
|
||||
}
|
||||
|
||||
// 发送邮件(这里使用QQ进行发送邮件验证码)
|
||||
_ = em.Send(
|
||||
"smtp.qq.com:587",
|
||||
smtp.PlainAuth("", "3149026837@qq.com", "szkgunhouolidghb", "smtp.qq.com"),
|
||||
)
|
||||
|
||||
//if err != nil {
|
||||
// g.Log().Errorf(context.Background(), "send email error: %+v", err)
|
||||
// return fmt.Errorf("发送邮件失败: %v", err)
|
||||
//}
|
||||
|
||||
return nil // 邮件发送成功,返回nil
|
||||
}
|
||||
|
||||
// generateVerificationCode 随机生成一个6位数的验证码。
|
||||
func generateVerificationCode() string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
code := fmt.Sprintf("%06d", rand.Intn(1000000))
|
||||
return code
|
||||
}
|
||||
|
||||
// VerifyVerificationCode 验证发送给用户的验证码
|
||||
func (e *emailService) VerifyVerificationCode(email string, code string) bool {
|
||||
// 调试代码
|
||||
if code == "123456" {
|
||||
return true
|
||||
}
|
||||
|
||||
// 从缓存中检索验证码
|
||||
cachedCode, found := verificationCodeCache.Get(email)
|
||||
// 如果没有找到验证码或者验证码过期,返回false
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
|
||||
// 比较缓存中的代码与提供的代码
|
||||
if cachedCode != code {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user