70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package activityclient
|
||
|
||
import (
|
||
"crypto/hmac"
|
||
"crypto/sha256"
|
||
"encoding/hex"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// 与 activity-public-server middleware/svcauth 协议保持一致:
|
||
//
|
||
// X-Svc-AppId : 调用方 appId
|
||
// X-Svc-Ts : 请求生成的 Unix 秒(服务端校验 ±300s)
|
||
// X-Svc-Sign : HMAC_SHA256(canonical, secret) 的 hex 小写
|
||
//
|
||
// canonical 串结构("\n" 分隔):
|
||
//
|
||
// appId
|
||
// ts
|
||
// METHOD // 大写
|
||
// path // URL.Path,不含 query
|
||
// rawQuery // URL.RawQuery 原样,不重排序
|
||
// sha256_hex(body) // 空 body 也参与运算
|
||
const (
|
||
headerSvcAppId = "X-Svc-AppId"
|
||
headerSvcTs = "X-Svc-Ts"
|
||
headerSvcSign = "X-Svc-Sign"
|
||
)
|
||
|
||
// BuildSvcHeaders 生成服务间调用鉴权头。
|
||
// method/path/rawQuery 必须与服务端 c.Request 上看到的一致;
|
||
// body 传原始字节(GET 等无 body 接口传 nil)。
|
||
// appId 或 secret 为空时返回 nil,调用方按未签名处理。
|
||
func BuildSvcHeaders(appId, secret, method, path, rawQuery string, body []byte) map[string]string {
|
||
if appId == "" || secret == "" {
|
||
return nil
|
||
}
|
||
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
||
return map[string]string{
|
||
headerSvcAppId: appId,
|
||
headerSvcTs: ts,
|
||
headerSvcSign: computeSvcSign(secret, appId, ts, strings.ToUpper(method), path, rawQuery, hashBody(body)),
|
||
}
|
||
}
|
||
|
||
// hashBody 计算 body 的 sha256 hex;nil/空 body 也返回 sha256("") 的 hex
|
||
func hashBody(body []byte) string {
|
||
sum := sha256.Sum256(body)
|
||
return hex.EncodeToString(sum[:])
|
||
}
|
||
|
||
// computeSvcSign 按 canonical 串拼接后做 HMAC-SHA256
|
||
func computeSvcSign(secret, appId, ts, method, path, rawQuery, bodyHash string) string {
|
||
h := hmac.New(sha256.New, []byte(secret))
|
||
h.Write([]byte(appId))
|
||
h.Write([]byte{'\n'})
|
||
h.Write([]byte(ts))
|
||
h.Write([]byte{'\n'})
|
||
h.Write([]byte(method))
|
||
h.Write([]byte{'\n'})
|
||
h.Write([]byte(path))
|
||
h.Write([]byte{'\n'})
|
||
h.Write([]byte(rawQuery))
|
||
h.Write([]byte{'\n'})
|
||
h.Write([]byte(bodyHash))
|
||
return hex.EncodeToString(h.Sum(nil))
|
||
}
|