Initial commit: 网络验证平台
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SmsService struct{}
|
||||
|
||||
func NewSmsService() *SmsService {
|
||||
return &SmsService{}
|
||||
}
|
||||
|
||||
type SmsConfig struct {
|
||||
Provider string
|
||||
AccessKey string
|
||||
SecretKey string
|
||||
SignName string
|
||||
TemplateCode string
|
||||
}
|
||||
|
||||
func (s *SmsService) SendSms(config SmsConfig, phone, code string) error {
|
||||
switch config.Provider {
|
||||
case "aliyun":
|
||||
return s.sendAliyunSms(config, phone, code)
|
||||
case "tencent":
|
||||
return s.sendTencentSms(config, phone, code)
|
||||
case "huawei":
|
||||
return s.sendHuaweiSms(config, phone, code)
|
||||
default:
|
||||
return fmt.Errorf("不支持的短信服务商: %s", config.Provider)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SmsService) sendAliyunSms(config SmsConfig, phone, code string) error {
|
||||
params := url.Values{}
|
||||
params.Set("AccessKeyId", config.AccessKey)
|
||||
params.Set("Action", "SendSms")
|
||||
params.Set("Format", "JSON")
|
||||
params.Set("PhoneNumbers", phone)
|
||||
params.Set("RegionId", "cn-hangzhou")
|
||||
params.Set("SignName", config.SignName)
|
||||
params.Set("SignatureMethod", "HMAC-SHA1")
|
||||
params.Set("SignatureNonce", fmt.Sprintf("%d", getTimeStamp()))
|
||||
params.Set("SignatureVersion", "1.0")
|
||||
params.Set("TemplateCode", config.TemplateCode)
|
||||
params.Set("TemplateParam", fmt.Sprintf(`{"code":"%s"}`, code))
|
||||
params.Set("Timestamp", getTimeStampStr())
|
||||
params.Set("Version", "2017-05-25")
|
||||
|
||||
signature := s.generateAliyunSignature(params, config.SecretKey)
|
||||
params.Set("Signature", signature)
|
||||
|
||||
resp, err := http.Get(fmt.Sprintf("https://dysmsapi.aliyuncs.com/?%s", params.Encode()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("请求阿里云短信API失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取响应失败: %v", err)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
Code string `json:"Code"`
|
||||
Message string `json:"Message"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return fmt.Errorf("解析响应失败: %v", err)
|
||||
}
|
||||
|
||||
if result.Code != "OK" {
|
||||
return fmt.Errorf("发送失败: %s", result.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SmsService) generateAliyunSignature(params url.Values, secretKey string) string {
|
||||
keys := make([]string, 0, len(params))
|
||||
for k := range params {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
encodedParams := make([]string, 0, len(params))
|
||||
for _, k := range keys {
|
||||
encodedParams = append(encodedParams, fmt.Sprintf("%s=%s", specialUrlEncode(k), specialUrlEncode(params.Get(k))))
|
||||
}
|
||||
sortParams := strings.Join(encodedParams, "&")
|
||||
|
||||
stringToSign := fmt.Sprintf("GET&%s&%s", specialUrlEncode("/"), specialUrlEncode(sortParams))
|
||||
|
||||
signature := hmacSHA1(secretKey+"&", stringToSign)
|
||||
return signature
|
||||
}
|
||||
|
||||
func (s *SmsService) sendTencentSms(config SmsConfig, phone, code string) error {
|
||||
return fmt.Errorf("腾讯云短信服务暂未实现")
|
||||
}
|
||||
|
||||
func (s *SmsService) sendHuaweiSms(config SmsConfig, phone, code string) error {
|
||||
return fmt.Errorf("华为云短信服务暂未实现")
|
||||
}
|
||||
|
||||
func (s *SmsService) SendTestSms(config SmsConfig, phone string) error {
|
||||
code := "123456"
|
||||
return s.SendSms(config, phone, code)
|
||||
}
|
||||
|
||||
func specialUrlEncode(s string) string {
|
||||
encoded := url.QueryEscape(s)
|
||||
encoded = strings.ReplaceAll(encoded, "+", "%20")
|
||||
encoded = strings.ReplaceAll(encoded, "*", "%2A")
|
||||
encoded = strings.ReplaceAll(encoded, "%7E", "~")
|
||||
return encoded
|
||||
}
|
||||
|
||||
func hmacSHA1(key, data string) string {
|
||||
return data
|
||||
}
|
||||
|
||||
func getTimeStamp() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func getTimeStampStr() string {
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user