```
feat(base): 添加邮箱注册码功能及用户注册接口 - 在 `sessionManager` 中新增邮件注册码缓存管理实例和相关方法 - 实现生成、保存、验证、删除邮件注册码的逻辑 - 新增 `/reg` 和 `/email` 接口用于用户注册和发送验证码 - 引入 `golang-lru` 依赖以支持限流缓存功能 - 调整包导入顺序,优化代码结构 ```
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/cool"
|
||||
v1 "blazing/modules/base/api/v1"
|
||||
"blazing/modules/base/model"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
@@ -8,8 +13,75 @@ import (
|
||||
"net"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
)
|
||||
|
||||
func (s *BaseSysLoginService) Reg(ctx context.Context, req *v1.BaseOpenLoginReq) (result *TokenResult, err error) {
|
||||
var (
|
||||
captchaId = req.CaptchaId
|
||||
verifyCode = req.VerifyCode
|
||||
password = req.Password
|
||||
username = req.Username
|
||||
baseSysUser = model.NewBaseSysUser()
|
||||
)
|
||||
|
||||
vcode, _ := cool.CacheManager.Get(ctx, "login:"+captchaId)
|
||||
if vcode.String() != verifyCode {
|
||||
err = gerror.New("验证码错误")
|
||||
return
|
||||
}
|
||||
md5password, _ := gmd5.Encrypt(password)
|
||||
|
||||
var user *model.BaseSysUser
|
||||
cool.DBM(baseSysUser).Where("username=?", username).Where("password=?", md5password).Where("status=?", 1).Scan(&user)
|
||||
if user == nil {
|
||||
err = gerror.New("账户或密码不正确~")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = s.generateTokenByUser(ctx, user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 10分钟内限制请求 ip->次数 邮箱->次数
|
||||
// 验证码对redis传,防止被重复操作
|
||||
// var emailcache = expirable.NewLRU[string, int](0, nil, time.Millisecond*10)
|
||||
var ipcache = expirable.NewLRU[string, int](0, nil, time.Millisecond*10)
|
||||
|
||||
func (s *BaseSysLoginService) Email(ctx context.Context, req *v1.BaseOpenEmailReq) (result *TokenResult, err error) {
|
||||
var (
|
||||
r = g.RequestFromCtx(ctx)
|
||||
//baseSysUser = model.NewBaseSysUser()
|
||||
)
|
||||
|
||||
ip := r.GetClientIp()
|
||||
v, ok := ipcache.Get(ip)
|
||||
if ok && v > 3 {
|
||||
|
||||
return nil, gerror.New("操作过于频繁,请稍后再试")
|
||||
|
||||
}
|
||||
ok, _ = share.ShareManager.EmailCodeExists(req.Email)
|
||||
if ok {
|
||||
return nil, gerror.New("注册码已下发 ")
|
||||
}
|
||||
// 发送验证码
|
||||
code, _ := share.ShareManager.SaveEmailCode(req.Email, time.Millisecond*10)
|
||||
SendVerificationCode(req.Email, code)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SMTPConfig 邮件发送配置
|
||||
type SMTPConfig struct {
|
||||
Host string // SMTP服务器地址
|
||||
@@ -93,10 +165,10 @@ const verificationCodeTemplate = `<!DOCTYPE html>
|
||||
// to: 收件人邮箱
|
||||
// code: 验证码
|
||||
// 返回错误信息
|
||||
func SendVerificationCode(to, code string) error {
|
||||
func SendVerificationCode(to string, code int) error {
|
||||
// 模板数据
|
||||
data := VerificationCodeData{
|
||||
Code: code,
|
||||
Code: gconv.String(code),
|
||||
ValidMin: 10, // 有效期10分钟
|
||||
Platform: "骄阳号", // 可替换为实际平台名称
|
||||
Hotline: "seersun.com", // 可替换为实际客服热线
|
||||
@@ -221,5 +293,5 @@ func SendMailWithTLS(addr string, auth smtp.Auth, from string,
|
||||
// TestSendVerificationCode 测试发送验证码邮件
|
||||
func TestSendVerificationCode() error {
|
||||
// 测试发送验证码为123456的邮件
|
||||
return SendVerificationCode("3361562035@qq.com", "123456")
|
||||
return SendVerificationCode("3361562035@qq.com", 123456)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user