增加短信宝

pull/701/head
miaowuawa 1 year ago
parent fe3693cc5b
commit c72f395722

@ -65,6 +65,11 @@ SmsJuhe:
Key: Key:
TplID: TplID:
TplVal: "#code#=%s&#m#=%d" TplVal: "#code#=%s&#m#=%d"
SmsBao:
Gateway: https://www.smsbao.com/
Username: xxx
Password: xxx
Sign: "【xxx】"
Alipay: Alipay:
AppID: AppID:
InProduction: True InProduction: True

@ -46,6 +46,7 @@ var (
BigCacheIndexSetting *bigCacheIndexConf BigCacheIndexSetting *bigCacheIndexConf
RedisCacheIndexSetting *redisCacheIndexConf RedisCacheIndexSetting *redisCacheIndexConf
SmsJuheSetting *smsJuheConf SmsJuheSetting *smsJuheConf
SmsBaoSetting *smsBaoConf
AlipaySetting *alipayConf AlipaySetting *alipayConf
TweetSearchSetting *tweetSearchConf TweetSearchSetting *tweetSearchConf
ZincSetting *zincConf ZincSetting *zincConf
@ -59,6 +60,7 @@ var (
LocalOSSSetting *localossConf LocalOSSSetting *localossConf
JWTSetting *jwtConf JWTSetting *jwtConf
WebProfileSetting *WebProfileConf WebProfileSetting *WebProfileConf
SmsType string
) )
func setupSetting(suite []string, noDefault bool) error { func setupSetting(suite []string, noDefault bool) error {
@ -76,6 +78,7 @@ func setupSetting(suite []string, noDefault bool) error {
objects := map[string]any{ objects := map[string]any{
"App": &AppSetting, "App": &AppSetting,
"SmsType": &SmsType,
"Cache": &CacheSetting, "Cache": &CacheSetting,
"EventManager": &EventManagerSetting, "EventManager": &EventManagerSetting,
"MetricManager": &MetricManagerSetting, "MetricManager": &MetricManagerSetting,
@ -96,6 +99,7 @@ func setupSetting(suite []string, noDefault bool) error {
"RedisCacheIndex": &RedisCacheIndexSetting, "RedisCacheIndex": &RedisCacheIndexSetting,
"Alipay": &AlipaySetting, "Alipay": &AlipaySetting,
"SmsJuhe": &SmsJuheSetting, "SmsJuhe": &SmsJuheSetting,
"SmsBao": &SmsBaoSetting,
"Pyroscope": &PyroscopeSetting, "Pyroscope": &PyroscopeSetting,
"Sentry": &sentrySetting, "Sentry": &sentrySetting,
"Logger": &loggerSetting, "Logger": &loggerSetting,

@ -183,6 +183,13 @@ type smsJuheConf struct {
TplVal string TplVal string
} }
type smsBaoConf struct {
Gateway string
Username string
Password string
Sign string
}
type tweetSearchConf struct { type tweetSearchConf struct {
MaxUpdateQPS int MaxUpdateQPS int
MinWorker int MinWorker int

@ -2,19 +2,17 @@ package security
import ( import (
"fmt" "fmt"
"github.com/rocboss/paopao-ce/internal/core"
"net/http" "net/http"
"time" "time"
"github.com/cockroachdb/errors" "github.com/cockroachdb/errors"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"gopkg.in/resty.v1" "gopkg.in/resty.v1"
) )
var ( var _ core.PhoneVerifyService = (*juheSmsServant)(nil)
_ core.PhoneVerifyService = (*juheSmsServant)(nil)
)
type juhePhoneCaptchaRsp struct { type juhePhoneCaptchaRsp struct {
ErrorCode int `json:"error_code"` ErrorCode int `json:"error_code"`

@ -0,0 +1,116 @@
package security
import (
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"io"
"net/http"
"net/url"
"strings"
"time"
"github.com/cockroachdb/errors"
)
var _ core.PhoneVerifyService = (*smsBaoServant)(nil)
// smsBaoPhoneCaptchaRsp 短信宝响应结构体
type smsBaoPhoneCaptchaRsp struct {
Status string `json:"status"` // 响应状态,如 success 或 error
Code string `json:"code"` // 状态码
Msg string `json:"msg"` // 状态消息
}
// smsBaoServant 短信宝服务结构体
type smsBaoServant struct {
gateway string
username string
password string
sign string
}
// SendPhoneCaptcha 发送短信验证码
func (s *smsBaoServant) SendPhoneCaptcha(phone string, captcha string, expire time.Duration) error {
// 对密码进行 MD5 加密
hasher := md5.New()
_, writeString := io.WriteString(hasher, s.password)
if writeString != nil {
return writeString
}
encryptedPassword := hex.EncodeToString(hasher.Sum(nil))
// 构建短信内容
content := fmt.Sprintf("%s您的验证码是:%s,有效期 %d 分钟。就算猫娘来你家也不要告诉她。", s.sign, captcha, int(expire.Minutes()))
// 对内容进行 URL 编码
encodedContent := url.QueryEscape(content)
// 构建请求 URL
requestURL := fmt.Sprintf("%s?u=%s&p=%s&m=%s&c=%s", s.gateway, s.username, encryptedPassword, phone, encodedContent)
// 发送 HTTP 请求
resp, err := http.Get(requestURL)
if err != nil {
return err
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
return errors.New(resp.Status)
}
// 读取响应内容
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
// 解析响应
result := &smsBaoPhoneCaptchaRsp{}
// 假设响应是简单的 text/plain 格式,按行分割
lines := strings.Split(string(body), "\n")
if len(lines) >= 1 {
result.Code = lines[0]
if len(lines) >= 2 {
result.Msg = strings.Join(lines[1:], "\n")
}
}
// 处理响应结果
switch result.Code {
case "0":
return nil
case "30":
return errors.New("密码错误!")
case "40":
return errors.New("账号不存在!")
case "41":
return errors.New("余额不足!")
case "42":
return errors.New("帐号过期!")
case "43":
return errors.New("IP地址限制!")
case "50":
return errors.New("内容含有敏感词!")
case "51":
return errors.New("手机号码不正确!")
case "-1":
return errors.New("手机号码不正确或缺少参数!")
default:
return errors.New(fmt.Sprintf("未知错误:%s - %s", result.Code, result.Msg))
}
}
// newSmsBaoServant 创建短信宝服务实例
func newSmsBaoServant() *smsBaoServant {
return &smsBaoServant{
gateway: conf.SmsBaoSetting.Gateway,
username: conf.SmsBaoSetting.Username,
password: conf.SmsBaoSetting.Password,
sign: conf.SmsBaoSetting.Sign,
}
}

@ -12,6 +12,8 @@ func NewPhoneVerifyService() core.PhoneVerifyService {
switch strings.ToLower(smsVendor) { switch strings.ToLower(smsVendor) {
case "smsjuhe": case "smsjuhe":
return newJuheSmsServant() return newJuheSmsServant()
case "smsbao":
return newSmsBaoServant()
default: default:
return newJuheSmsServant() return newJuheSmsServant()
} }

Loading…
Cancel
Save