package aes import ( "applet/app/lib/aes/md" "applet/app/utils" "bytes" "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" "io/ioutil" "strconv" "strings" "time" ) func CheckSign(c *gin.Context) error { var query = map[string]string{} //1、从请求头中获取必传参数 query["timestamp"] = c.GetHeader("timestamp") query["nonce"] = c.GetHeader("nonce") if len(query["nonce"]) != 32 { return errors.New("随机字符串有误!") } sign := c.GetHeader("sign") //2、判断请求方式,以获取请求参数 if c.Request.Method == "GET" { queryParams := c.Request.URL.Query() for key, values := range queryParams { if len(values) > 0 { query[key] = values[0] } } } else { body, _ := ioutil.ReadAll(c.Request.Body) if string(body) != "" { fmt.Println("body:" + string(body)) str, err := AesDecryptByECB(md.AesKey, string(body)) if err != nil { return err } if str != "" { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(str))) var bodyParams = map[string]interface{}{} err = json.Unmarshal([]byte(str), &bodyParams) if err != nil { return err } for key, value := range bodyParams { // 使用类型断言判断是否为 string 类型 if _, ok := value.(map[string]interface{}); ok { query[key] = utils.SerializeStr(value) } else { query[key] = utils.AnyToString(value) } } } } } //3.query参数按照 ASCII 码从小到大排序 str := utils.JoinStringsInASCII(query, "&", false, false, "") //4.md5加密 转小写 signValue := strings.ToLower(utils.Md5(str)) //5.判断跟前端传来的sign是否一致 if sign != signValue { return errors.New("非法签名!") } //6、判断时效性 currentTimestamp := time.Now().Unix() storedTimestamp, err := strconv.ParseInt(query["timestamp"], 10, 64) if err != nil { return err } if isMillisecond(storedTimestamp) { //TODO::兼容客户端传毫秒 currentTimestamp = time.Now().UnixMilli() if currentTimestamp-storedTimestamp > 60*5*1000 { // 2分钟 fmt.Println("currentTimestamp>>>>>:", currentTimestamp) fmt.Println("storedTimestamp>>>>>:", storedTimestamp) return fmt.Errorf("签名过期~") } if currentTimestamp-storedTimestamp < -60*1000 { //避免客户端传过快时间的误差 return errors.New("签名超前~") } } else { if currentTimestamp-storedTimestamp > 60*5 { // 2分钟 fmt.Println("currentTimestamp>>>>>:", currentTimestamp) fmt.Println("storedTimestamp>>>>>:", storedTimestamp) return fmt.Errorf("签名过期!") } if currentTimestamp-storedTimestamp < -60 { //避免客户端传过快时间的误差 return errors.New("签名超前!") } } return nil } func isMillisecond(timestamp int64) bool { return timestamp > 1e12 && timestamp < 1e13 }