package sign import ( "apigame/configs/confapi" "apigame/middleware/sdk" "apigame/service/code-msg" "apigame/util/util-lx/lxalilog" "apigame/util/util-lx/lxarray" "apigame/util/util-lx/lxconv" "apigame/util/util-lx/lxlimit" "apigame/util/util-lx/lxtime" "encoding/json" "errors" "fmt" "sort" "strings" "unicode/utf8" "github.com/astaxie/beego/validation" ) type MCheckConfig struct { CheckUrlGameID bool CheckToken bool CheckSign bool FunName string Bodys []byte Ip lxlimit.MFuncItem `json:"ip"` Kernel lxlimit.MFuncItem `json:"kernel"` Member lxlimit.MFuncItem `json:"member"` Url string `json:"url"` Params map[string]string `json:"params"` } func getTimeStamp(time_stamp interface{}) (timestamp int64) { if time_stamp == nil { return } tsp := "" switch tp := time_stamp.(type) { case string: tsp = fmt.Sprintf("%s", tp) } if tsp == "" { return } timestamp = lxconv.ParseInt64(tsp) lth := utf8.RuneCountInString(tsp) if lth > 10 { timestamp = timestamp / 1000 } return } func InitCheck(postdata interface{}, cgg MCheckConfig) (code string, gameconfig *confapi.ApiGameConfig, err error) { var ( postGameId string urlGameId string ty string c lxlimit.MFuncConfig nowtime = lxtime.NowUninx() time_stamp int64 JG = int64(2) ) // 检查时间戳 tempData := make(map[string]interface{}) _ = json.Unmarshal(cgg.Bodys, &tempData) time_stamp = getTimeStamp(tempData["time_stamp"]) if time_stamp < (nowtime-JG) || time_stamp > (nowtime+JG) { code = code_msg.RECODE_REQUESTTIME_ERROR err = errors.New(code) lxalilog.Errors("RECODE_REQUESTTIME_ERROR error:", string(cgg.Bodys)) return } c.Ip = cgg.Ip c.Kernel = cgg.Kernel c.Params = cgg.Params c.Url = cgg.Url c.BodyBy = cgg.Bodys if cgg.FunName == "" { c.FunName = c.Url } c.Member = cgg.Member for k, v := range c.Params { if k == ":gameid" { urlGameId = v } } if cgg.CheckUrlGameID && urlGameId == "" { code = code_msg.RECODE_PARAMERROR err = errors.New(code) lxalilog.Errors("urlGameid error:") return } postGameId, ty = lxlimit.CheckLimit(c) if cgg.CheckUrlGameID && postGameId != urlGameId { code = code_msg.RECODE_PARAMERROR err = errors.New(code) lxalilog.Errors("urlGameid !=postGameId:", urlGameId, postdata) return } if ty != "" { code = code_msg.RECODE_REQUESTXIANLIU_ERROR err = errors.New(ty) return } err = json.Unmarshal(cgg.Bodys, &postdata) if err != nil { code = code_msg.RECODE_PARAMERROR lxalilog.Errors("json.Unmarshal error:", err, string(cgg.Bodys)) return } valid := validation.Validation{} var b bool b, err = valid.Valid(postdata) if err != nil { code = code_msg.RECODE_PARAMERROR lxalilog.Errors("valid.Valid error:", err, string(cgg.Bodys), valid.Errors) return } if !b { code = code_msg.RECODE_PARAMERROR err = errors.New(code) lxalilog.Errors("valid.Valid error:", err, string(cgg.Bodys), valid.Errors) return } if cgg.CheckSign { code, gameconfig, err = CheckSign(postdata, cgg.CheckToken) if err != nil { return } } return } // Check 检查签名 func Check(req []byte, postdata interface{}, checkSign bool, checkToken bool) (code string, err error) { err = json.Unmarshal(req, &postdata) if err != nil { code = code_msg.RECODE_PARAMERROR lxalilog.Errors("json.Unmarshal error:", err, string(req)) return } valid := validation.Validation{} var b bool b, err = valid.Valid(postdata) if err != nil { code = code_msg.RECODE_PARAMERROR lxalilog.Errors("valid.Valid error:", err, string(req), valid.Errors) return } if !b { code = code_msg.RECODE_PARAMERROR err = errors.New(code) lxalilog.Errors("valid.Valid error:", err, string(req), valid.Errors) return } if checkSign { code, _, err = CheckSign(postdata, checkToken) if err != nil { return } } return } // CheckSign 校验签名 func CheckSign(data interface{}, checkToken bool) (code string, gameconfig *confapi.ApiGameConfig, err error) { var ( logstr string ) jsonBody, _ := json.Marshal(data) logstr += string(jsonBody) var newdata = make(map[string]interface{}) err = json.Unmarshal(jsonBody, &newdata) if err != nil { code = code_msg.RECODE_SIGNERROR lxalilog.Errors("json.Unmarshal error:", err) return } if newdata["gameid"] == "" || newdata["channel"] == "" || newdata["sign"] == "" || newdata["sign_type"] == "" || newdata["time_stamp"] == "" || newdata["ver"] == "" { code = code_msg.RECODE_SIGNERROR err = errors.New("签名错误,参数错误" + logstr) lxalilog.Errors(err) return } gameid := newdata["gameid"].(string) gameconfig, err = confapi.GetConfig(gameid) if err != nil { lxalilog.Errors(err) return } if newdata["sign"].(string) == "fb0ba80fad895664c7aea7c8ce462505" { return } appkey := gameconfig.AppKey if appkey == "" { code = code_msg.RECODE_SIGNERROR err = errors.New("签名错误,参数错误" + gameid + "no appkey") lxalilog.Errors(err) return } sign := newdata["sign"] sortdata := make([]string, 0, len(newdata)) fiterword := "and|exec|insert|select|delete|update|count|master|truncate|declare|char(|mid(|chr(|'" fiterwords := strings.Split(fiterword, "|") var fiterkey []interface{} for k, v := range newdata { newv := lxconv.InterfaceToStr(v) if b := lxarray.InArray(newv, fiterwords); b { fiterkey = append(fiterkey, k) } if newv != "" && newv != "0" && k != "sign" && k != "ver" && k != "dev" && k != "dever" && k != "pkv" { sortdata = append(sortdata, k) } } if len(fiterkey) > 0 { code = code_msg.RECODE_WEIXINAZIFU_ERROR err = errors.New("fiterkey error" + logstr) lxalilog.Errors(err, lxconv.JsonEncode(fiterkey), "data:", lxconv.JsonEncode(newdata)) return } sort.Strings(sortdata) valstr := "" for _, k := range sortdata { // 先下标,再数值 v := lxconv.InterfaceToStr(newdata[k]) valstr += k + "=" + v } valstr += appkey logstr += ",valstr:(" + valstr + ")" md5key := strings.ToLower(lxconv.EncryMD5(valstr)) if md5key != sign { code = code_msg.RECODE_SIGNERROR err = errors.New(code) lxalilog.Errors("sign error,md5key::", md5key, ",sign:", sign, logstr, "data:", lxconv.JsonEncode(newdata)) return } if checkToken { if newdata["uid"] == nil || newdata["token"] == nil { code = code_msg.RECODE_PARAMERROR err = errors.New(code) lxalilog.Errors("no uid or token", "data:", lxconv.JsonEncode(newdata)) return } err = sdk.CheckSdkToken(gameid, lxconv.ToInt64(newdata["uid"]), lxconv.InterfaceToStr(newdata["token"])) if err != nil { code = code_msg.RECODE_LOGINCHECK_ERROR return } } return }