使用Go实现验证码发送服务

使用Go实现验证码发送服务

邮箱服务配置

这里我们选择qq邮箱作为案例

使用第三包实现邮件服务配置

1
go get github.com/jordan-wright/email

利用Redis中的string的可设置过期这一特性

配置 Redis

导入redis的包

1
go get github.com/go-redis/redis/v8

初始化redis

1
2
3
4
5
6
7
8
9
var RDB = InitRedis("localhost:6379")

func InitRedis(addr string) *redis.Client {
return redis.NewClient(&redis.Options{
Addr: addr,
Password: "", // no password set
DB: 0, // use default DB
})
}

Go验证码服务逻辑

我们使用Redis存储邮箱-验证码的键值对,并设置过期时间。

如将过期时间设置为5分钟,那么在一对键值对插入数据库的5分钟后Redis就会将其删除。这样就实现了验证码在一定时间后过期失效的功能。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
func TestEmail(t *testing.T) {
e := email.NewEmail()
e.From = "yansaitao@qq.com"
e.To = []string{"2674978072@qq.com"}

e.Subject = "Validation Code Sending Test"
e.HTML = []byte("<h1>Your Validation Code is " + helper.GenerateRandomCode() + "</h1>")
err := e.SendWithTLS("smtp.qq.com:465", smtp.PlainAuth("", "yansaitao@qq.com", defined.MailPassword, "smtp.qq.com"),
&tls.Config{InsecureSkipVerify: true, ServerName: "smtp.qq.com"})
if err != nil {
t.Fatal(err)
}
}

这里我们注意

  • smtp的端口号为25,但这里需要安全登录,所以我们需要使用 465端口来实现加密通信,以满足安全需求
  • defined.MailPassword 为第一步中设置qq邮箱,所得到的授权码

生成随机验证码

1
2
3
4
5
6
7
8
9
10
func GenerateRandomCode() string {
s := "1234567890"
code := ""
// import random seed, or that random code will always be the same one
rand.Seed(time.Now().UnixNano())
for i := 0; i < defined.CodeLength; i++ {
code += string(s[rand.Intn(len(s))])
}
return code
}

其中的 defined.CodeLength为自定义验证码长度

具体的业务逻辑实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (l *MailCodeSendRegisterLogic) MailCodeSendRegister(req *types.MailCodeSendRequest) (resp *types.MailCodeSendReply, err error) {
// check whether the email has been registered
cnt, err := l.svcCtx.Engine.Where("email = ?", req.Email).Count(new(model.UserBasic))
if err != nil {
return
}
if cnt > 0 {
err = errors.New("this Email has registered before")
return
}

// generate random validation code
code := helper.GenerateRandomCode()

// store the email-code kv pair into
l.svcCtx.RDB.Set(l.ctx, req.Email, code, time.Second*time.Duration(defined.CodeExpirationTime))

err = helper.MailSendCode(req.Email, code)
resp = &types.MailCodeSendReply{Code: code}
return
}

其中 CodeExpirationTime为过期的时间,单位为秒


使用Go实现验证码发送服务
http://example.com/2023/10/17/使用Go实现验证码发送服务/
作者
Forrest
发布于
2023年10月17日
许可协议