// GenerateSignature 生成签名
// secret: app_secret
// method: HTTP Method,例如 GET / POST
// path: URL Path,例如 /partner/v1/user/token
// queryParams: URL 查询参数
// headerParams: 公共 Header 参数
// body: POST Body(json)
func GenerateSignature(secret, method, path string,
queryParams url.Values,
headerParams map[string]string,
body []byte) string {
// 1. 合并参数
allParams := make(map[string]string)
for k, v := range headerParams {
allParams[k] = v
}
for k, v := range queryParams {
if len(v) > 0 {
allParams[k] = v[0]
}
}
// 2. 字典序排序
var keys []string
for k := range allParams {
keys = append(keys, k)
}
sort.Strings(keys)
// 3. 构造签名原串
var sb strings.Builder
sb.WriteString(strings.ToUpper(method))
sb.WriteString(path)
for _, k := range keys {
sb.WriteString(k)
sb.WriteString(allParams[k])
}
// 4. 拼接 body
if len(body) > 0 {
sb.Write(body)
}
// 5. HMAC-SHA256
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(sb.String()))
return hex.EncodeToString(h.Sum(nil))
}