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 currentTimestamp-storedTimestamp > 300 { // 5分钟 return fmt.Errorf("签名过期!") } return nil }