third-platform-sdk/platform/meituan-media/sign.go
2024-06-23 22:22:52 +08:00

121 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package meituan_media
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"sort"
"strings"
"time"
"gitee.com/chengdu-lenntc/third-platform-sdk/util"
)
type Sign struct {
AppKey string // 应用key
AppSecret string // 应用秘钥
}
func newSign(appKey, appSecret string) *Sign {
return &Sign{
AppKey: appKey,
AppSecret: appSecret,
}
}
func (s *Sign) BuildHeader(methodType string, uri string, data map[string]any) map[string]string {
headers := map[string]string{
SCaApp: s.AppKey, // 应用app_key
SCaTimestamp: fmt.Sprintf("%d", time.Now().UnixMilli()), // 请求发起时间戳(毫秒)有效时1分钟
SCaSignatureHeaders: "S-Ca-Timestamp,S-Ca-App", // 将需要签名的header
ContentMd5: s.contentMD5(methodType, data), // body数据Md5加密
//"Content-Type": "application/json",
}
headers[SCaSignature] = s.GetSign(methodType, uri, data, headers)
return headers
}
func (s *Sign) GetSign(methodType string, uri string, data map[string]any, signHeaders map[string]string) string {
httpMethod := s.httpMethod(methodType)
contentMD5 := s.contentMD5(methodType, data)
headers := s.headers(signHeaders)
url := s.url(methodType, uri, data)
strSign := httpMethod + "\n" + contentMD5 + "\n" + headers + url
hm := hmac.New(sha256.New, []byte(s.AppSecret))
hm.Write([]byte(strSign))
signStr := base64.StdEncoding.EncodeToString(hm.Sum(nil))
return signStr
}
// 请求方式大写
func (s *Sign) httpMethod(methodType string) string {
return strings.ToUpper(methodType)
}
// 请求参数执行base64+md5的值
func (s *Sign) contentMD5(methodType string, data map[string]any) string {
methodType = s.httpMethod(methodType)
if (methodType == http.MethodPost || methodType == http.MethodPut) && data != nil {
dataByte, _ := json.Marshal(data)
h := md5.New()
h.Write(dataByte)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
} else {
return ""
}
}
// 签名计算Header的Key拼接
func (s *Sign) headers(signHeaders map[string]string) string {
var str = ""
// key排序
sortData := sort.StringSlice{}
for k := range signHeaders {
if k != SCaSignature && k != SCaSignatureHeaders && k != ContentMd5 {
sortData = append(sortData, k)
}
}
sortData.Sort()
for _, k := range sortData {
str += k + ":" + signHeaders[k] + "\n"
}
return str
}
// url拼接
// post直接返回pathget有参数的情况下拼接url
func (s *Sign) url(methodType, uri string, data map[string]any) string {
var query = ""
methodType = s.httpMethod(methodType)
// key排序
sortData := sort.StringSlice{}
for k := range data {
sortData = append(sortData, k)
}
sortData.Sort()
if len(sortData) > 0 && methodType == http.MethodGet {
for num, key := range sortData {
value, err := util.ToString(data[key])
if err != nil {
return ""
}
str1 := ""
if len(sortData)-1 != num {
str1 = "&"
}
if len(value) > 0 {
query += fmt.Sprintf("%s=%s", key, value)
} else {
query += key
}
query += str1
}
}
return fmt.Sprintf("%s%s", uri, query)
}