问题背景
func CheckSign(c *gin.Context, signKey string, singExpire int) (string, error) {
r := c.Request
var formParams map[string]interface{}
if c.Request.Body != nil {
bodyBytes, _ := io.ReadAll(c.Request.Body)
defer c.Request.Body.Close()
if len(bodyBytes) > 0 {
//原始有问题的写法
//err := json.Unmarshal(bodyBytes, &formParams)
// 直接解析,会导致数字类型解析出来的是科学计数法
d := json.NewDecoder(bytes.NewReader([]byte(bodyBytes)))
d.UseNumber()
err := d.Decode(&formParams)
if err != nil {
return "", err
}
}
// 创建新的reader,使用bytes.NewReader
// 恢复r.Body,以便可以多次读取
r.Body = io.NopCloser(bytes.NewReader(bodyBytes))
}
sign := c.GetHeader("api-sign")
timestamp := c.GetHeader("api-timestamp")
if sign == "" || timestamp == "" {
return "", errors.New("api-sign 或 api-timestamp为空")
}
//验证时间戳格式
timestampValue, err := strconv.ParseInt(timestamp, 10, 64)
if err != nil {
return "", errors.New("timetamp 格式错误")
}
//验证时间戳
nowstamp := time.Now().UnixNano() / int64(time.Millisecond)
ago := timestampValue + int64(singExpire)
if nowstamp > ago {
return "", errors.New("签名时间已过期")
}
//验证签名