You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.0 KiB
142 lines
3.0 KiB
package request
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"git.oa00.com/go/otosaas/config"
|
|
"github.com/google/uuid"
|
|
"github.com/tjfoc/gmsm/sm4"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
POST = "POST"
|
|
GET = "GET"
|
|
)
|
|
|
|
var client = &http.Client{}
|
|
|
|
// Request @Title 请求
|
|
func Request(method, url, data string, headers ...map[string]string) ([]byte, error) {
|
|
reqest, err := http.NewRequest(method, url, strings.NewReader(data))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(headers) > 0 {
|
|
for key, value := range headers[0] {
|
|
reqest.Header.Add(key, value)
|
|
}
|
|
}
|
|
response, err := client.Do(reqest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer response.Body.Close()
|
|
result, err := io.ReadAll(response.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// Encrypt @Title 加密
|
|
func Encrypt(data string) (string, error) {
|
|
bytes, err := sm4.Sm4Ecb(config.SdkConfig.Sm4Secret, []byte(data), true)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(bytes), nil
|
|
}
|
|
|
|
// Decrypt @Title 解密
|
|
func Decrypt(data string) (string, error) {
|
|
decodeString, err := hex.DecodeString(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
bytes, err := sm4.Sm4Ecb(config.SdkConfig.Sm4Secret, decodeString, false)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(bytes), nil
|
|
}
|
|
|
|
// Sign @Title 签名
|
|
func Sign(data, timeStamp string) (sign string, err error) {
|
|
signData, err := config.SdkConfig.PrivateKey.Sign(rand.Reader, []byte(config.SdkConfig.AppSecret+timeStamp+data), nil)
|
|
if err != nil {
|
|
return sign, err
|
|
}
|
|
return base64.StdEncoding.EncodeToString(signData), nil
|
|
}
|
|
|
|
type response struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
BizData string `json:"bizData"`
|
|
Sign string `json:"sign"`
|
|
}
|
|
|
|
// Exec 调用接口
|
|
func Exec(action string, data interface{}, resObj interface{}) error {
|
|
// 加密
|
|
marshal, _ := json.Marshal(&data)
|
|
log.Println(string(marshal))
|
|
encrypt, err := Encrypt(string(marshal))
|
|
if err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
// 签名
|
|
timeStamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
|
|
sign, err := Sign(encrypt, timeStamp)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
|
|
bytes, _ := json.Marshal(map[string]string{
|
|
"bizData": encrypt,
|
|
"sign": sign,
|
|
})
|
|
|
|
// 调用接口
|
|
result, err := Request(POST, config.SdkConfig.Url+action, string(bytes), map[string]string{
|
|
"Content-Type": "application/json",
|
|
"appKey": config.SdkConfig.AppKey,
|
|
"timeStamp": timeStamp,
|
|
"version": "1.0",
|
|
"requestId": uuid.New().String(),
|
|
})
|
|
if err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
log.Println(string(result))
|
|
resp := response{}
|
|
if err = json.Unmarshal(result, &resp); err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
if resp.Code == 0 {
|
|
decrypt, err := Decrypt(resp.BizData)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
log.Println(decrypt)
|
|
return json.Unmarshal([]byte(decrypt), &resObj)
|
|
} else {
|
|
return errors.New(resp.Message)
|
|
}
|
|
|
|
}
|