From 745f3639d5c7e65ec40322c1d2e0e46ea5e5af80 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Fri, 16 Dec 2022 10:54:01 +0800 Subject: [PATCH] optimize phone sms verify logic code --- config.yaml.sample | 2 +- go.mod | 2 +- go.sum | 4 +- internal/core/security.go | 9 ++- internal/dao/jinzhu/jinzhu.go | 3 +- internal/dao/jinzhu/security.go | 61 +++++------------ .../{attachment.go => attachment_check.go} | 4 ++ internal/dao/security/phone_verify_juhe.go | 66 +++++++++++++++++++ internal/dao/security/security.go | 18 +++++ 9 files changed, 117 insertions(+), 52 deletions(-) rename internal/dao/security/{attachment.go => attachment_check.go} (87%) create mode 100644 internal/dao/security/phone_verify_juhe.go create mode 100644 internal/dao/security/security.go diff --git a/config.yaml.sample b/config.yaml.sample index d776769b..d9da6327 100644 --- a/config.yaml.sample +++ b/config.yaml.sample @@ -23,7 +23,7 @@ SmsJuhe: Gateway: https://v.juhe.cn/sms/send Key: TplID: - TplVal: "#code#=%d&#m#=%d" + TplVal: "#code#=%s&#m#=%d" Alipay: AppID: InProduction: True diff --git a/go.mod b/go.mod index 0215af0f..c56c4adb 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868 - github.com/alimy/cfg v0.1.0 + github.com/alimy/cfg v0.3.0 github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible github.com/allegro/bigcache/v3 v3.0.2 github.com/bytedance/sonic v1.5.0 diff --git a/go.sum b/go.sum index 7262bc9a..58b7f668 100644 --- a/go.sum +++ b/go.sum @@ -142,8 +142,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= -github.com/alimy/cfg v0.1.0 h1:J7KDLEoVIjEBMGlQJb2ljad/d49gJ4Tsl2ogZ9XNhaY= -github.com/alimy/cfg v0.1.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c= +github.com/alimy/cfg v0.3.0 h1:9xgA0QWVCPSq9fFNRcYahVCAX22IL9ts2wrTQPfAStY= +github.com/alimy/cfg v0.3.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= diff --git a/internal/core/security.go b/internal/core/security.go index 63a7ac21..a5c9045f 100644 --- a/internal/core/security.go +++ b/internal/core/security.go @@ -1,6 +1,8 @@ package core import ( + "time" + "github.com/rocboss/paopao-ce/internal/model" ) @@ -11,7 +13,12 @@ type SecurityService interface { SendPhoneCaptcha(phone string) error } -// 附件检测服务 +// AttachmentCheckService 附件检测服务 type AttachmentCheckService interface { CheckAttachment(uri string) error } + +// PhoneVerifyService 手机验证服务 +type PhoneVerifyService interface { + SendPhoneCaptcha(phone string, captcha string, expire time.Duration) error +} diff --git a/internal/dao/jinzhu/jinzhu.go b/internal/dao/jinzhu/jinzhu.go index b3eb550f..0451670b 100644 --- a/internal/dao/jinzhu/jinzhu.go +++ b/internal/dao/jinzhu/jinzhu.go @@ -42,6 +42,7 @@ func NewDataService() (core.DataService, core.VersionInfo) { v core.VersionInfo ) db := conf.MustGormDB() + pvs := security.NewPhoneVerifyService() i := newIndexPostsService(db) if cfg.If("SimpleCacheIndex") { @@ -67,7 +68,7 @@ func NewDataService() (core.DataService, core.VersionInfo) { CommentManageService: newCommentManageService(db), UserManageService: newUserManageService(db), ContactManageService: newContactManageService(db), - SecurityService: newSecurityService(db), + SecurityService: newSecurityService(db, pvs), AttachmentCheckService: security.NewAttachmentCheckService(), } return ds, ds diff --git a/internal/dao/jinzhu/security.go b/internal/dao/jinzhu/security.go index dfbe2c74..5ea1ea25 100644 --- a/internal/dao/jinzhu/security.go +++ b/internal/dao/jinzhu/security.go @@ -1,18 +1,12 @@ package jinzhu import ( - "errors" - "fmt" "math/rand" - "net/http" "strconv" "time" - "github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/model" - "github.com/rocboss/paopao-ce/pkg/json" - "gopkg.in/resty.v1" "gorm.io/gorm" ) @@ -21,71 +15,46 @@ var ( ) type securityServant struct { - db *gorm.DB + db *gorm.DB + phoneVerify core.PhoneVerifyService } -func newSecurityService(db *gorm.DB) core.SecurityService { +func newSecurityService(db *gorm.DB, phoneVerify core.PhoneVerifyService) core.SecurityService { return &securityServant{ - db: db, + db: db, + phoneVerify: phoneVerify, } } -type juhePhoneCaptchaRsp struct { - ErrorCode int `json:"error_code"` - Reason string `json:"reason"` -} - -// 获取最新短信验证码 +// GetLatestPhoneCaptcha 获取最新短信验证码 func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) { return (&model.Captcha{ Phone: phone, }).Get(s.db) } -// 更新短信验证码 +// UsePhoneCaptcha 更新短信验证码 func (s *securityServant) UsePhoneCaptcha(captcha *model.Captcha) error { captcha.UseTimes++ return captcha.Update(s.db) } -// 发送短信验证码 +// SendPhoneCaptcha 发送短信验证码 func (s *securityServant) SendPhoneCaptcha(phone string) error { - rand.Seed(time.Now().UnixNano()) - captcha := rand.Intn(900000) + 100000 - m := 5 - - client := resty.New() - client.DisableWarn = true - resp, err := client.R(). - SetFormData(map[string]string{ - "mobile": phone, - "tpl_id": conf.SmsJuheSetting.TplID, - "tpl_value": fmt.Sprintf(conf.SmsJuheSetting.TplVal, captcha, m), - "key": conf.SmsJuheSetting.Key, - }).Post(conf.SmsJuheSetting.Gateway) - if err != nil { - return err - } + expire := time.Duration(5) - if resp.StatusCode() != http.StatusOK { - return errors.New(resp.Status()) - } - - result := &juhePhoneCaptchaRsp{} - err = json.Unmarshal(resp.Body(), result) - if err != nil { + // 发送验证码 + rand.Seed(time.Now().UnixNano()) + captcha := strconv.Itoa(rand.Intn(900000) + 100000) + if err := s.phoneVerify.SendPhoneCaptcha(phone, captcha, expire); err != nil { return err } - if result.ErrorCode != 0 { - return errors.New(result.Reason) - } - // 写入表 captchaModel := &model.Captcha{ Phone: phone, - Captcha: strconv.Itoa(captcha), - ExpiredOn: time.Now().Add(time.Minute * time.Duration(m)).Unix(), + Captcha: captcha, + ExpiredOn: time.Now().Add(expire * time.Minute).Unix(), } captchaModel.Create(s.db) return nil diff --git a/internal/dao/security/attachment.go b/internal/dao/security/attachment_check.go similarity index 87% rename from internal/dao/security/attachment.go rename to internal/dao/security/attachment_check.go index 3bd79461..2425220b 100644 --- a/internal/dao/security/attachment.go +++ b/internal/dao/security/attachment_check.go @@ -8,6 +8,10 @@ import ( "github.com/rocboss/paopao-ce/internal/core" ) +var ( + _ core.AttachmentCheckService = (*attachmentCheckServant)(nil) +) + type attachmentCheckServant struct { domain string } diff --git a/internal/dao/security/phone_verify_juhe.go b/internal/dao/security/phone_verify_juhe.go new file mode 100644 index 00000000..5981c6c3 --- /dev/null +++ b/internal/dao/security/phone_verify_juhe.go @@ -0,0 +1,66 @@ +package security + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/rocboss/paopao-ce/internal/conf" + "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/pkg/json" + "gopkg.in/resty.v1" +) + +var ( + _ core.PhoneVerifyService = (*juheSmsServant)(nil) +) + +type juhePhoneCaptchaRsp struct { + ErrorCode int `json:"error_code"` + Reason string `json:"reason"` +} + +type juheSmsServant struct { + gateway string + key string + tplID string + tplVal string +} + +// SendPhoneCaptcha 发送短信验证码 +func (s *juheSmsServant) SendPhoneCaptcha(phone string, captcha string, expire time.Duration) error { + client := resty.New() + client.DisableWarn = true + resp, err := client.R(). + SetFormData(map[string]string{ + "mobile": phone, + "tpl_id": s.tplID, + "tpl_value": fmt.Sprintf(s.tplVal, captcha, expire), + "key": s.key, + }).Post(s.gateway) + if err != nil { + return err + } + if resp.StatusCode() != http.StatusOK { + return errors.New(resp.Status()) + } + + result := &juhePhoneCaptchaRsp{} + if err = json.Unmarshal(resp.Body(), result); err != nil { + return err + } + if result.ErrorCode != 0 { + return errors.New(result.Reason) + } + return nil +} + +func newJuheSmsServant() *juheSmsServant { + return &juheSmsServant{ + gateway: conf.SmsJuheSetting.Gateway, + key: conf.SmsJuheSetting.Key, + tplID: conf.SmsJuheSetting.TplID, + tplVal: conf.SmsJuheSetting.TplVal, + } +} diff --git a/internal/dao/security/security.go b/internal/dao/security/security.go new file mode 100644 index 00000000..75cd003b --- /dev/null +++ b/internal/dao/security/security.go @@ -0,0 +1,18 @@ +package security + +import ( + "strings" + + "github.com/alimy/cfg" + "github.com/rocboss/paopao-ce/internal/core" +) + +func NewPhoneVerifyService() core.PhoneVerifyService { + smsVendor, _ := cfg.Val("sms") + switch strings.ToLower(smsVendor) { + case "smsjuhe": + return newJuheSmsServant() + default: + return newJuheSmsServant() + } +}