package middleware import ( "fmt" "net/http" "net/url" "sort" "strconv" "strings" "time" "bet24.com/log" "bet24.com/public" "bet24.com/servers/payment/config" "github.com/gin-gonic/gin" "github.com/pkg/errors" "github.com/unrolled/secure" ) // 身份验证(MD5) func CheckValid() gin.HandlerFunc { return func(c *gin.Context) { //验证签名 //if _, err := verifySign(c); err != nil { // // _ = c.Request.ParseForm() // log.Error("IPAddress[%v] checkValid sign is error %v", // c.Request.RemoteAddr, err) // // c.Abort() // return //} _ = c.Request.ParseForm() req := c.Request.Form path := c.Request.URL.Path rawPath := c.Request.URL.RawPath log.Debug("%s ==> %s", path, req) start := time.Now() c.Next() //记录耗时信息 if latency := time.Now().Sub(start); latency > 10*time.Second { log.Release("%v %v 访问耗时 %v =====> %+v", path, rawPath, latency, req) } } } // 验证签名 func verifySign(c *gin.Context) (bool, error) { _ = c.Request.ParseForm() req := c.Request.Form ts := strings.Join(c.Request.Form["TimeStamp"], "") sn := strings.Join(c.Request.Form["Sign"], "") url := c.Request.URL.RequestURI() //log.Release("verifySign req=%+v", req) if ts == "" || sn == "" { return false, errors.New(fmt.Sprintf("%v GetQuery Error TimeStamp=%s Sign=%s", url, ts, sn)) } //验证过期时间(5分钟) timeStamp := time.Now().Unix() var exp int64 = 5 * 60 * 60 tsInt, _ := strconv.ParseInt(ts, 10, 64) if timeStamp-tsInt >= exp { return false, errors.New(fmt.Sprintf("%v timeStamp Error timeStamp=%d tsInt=%d exp=%d", url, timeStamp, tsInt, exp)) } // 加密串 checkContent := createEncryptStr(req) + fmt.Sprintf("&key=%s", config.Server.WebKey) //log.Debug("createSign MD5加密前=%s", checkContent) sign := public.GetMd5String(checkContent) //log.Debug("verifySign MD5加密后=%s", sign) //验证签名 if sn == "" || sn != sign { return false, errors.New(fmt.Sprintf("%v sign error ReqParams=%+v Pequest[Sign]=%s checkContent=%s sign=%s", url, req, sn, checkContent, sign)) } return true, nil } // 创建加密串 func createEncryptStr(params url.Values) string { var key []string var str = "" for k := range params { if k != "Sign" { key = append(key, k) } } sort.Strings(key) for i := 0; i < len(key); i++ { if i != 0 { str = str + "&" } //log.Debug("key[%v]=%v", i, str) str = str + fmt.Sprintf("%v=%v", key[i], params.Get(key[i])) } return str } // 跨域中间件 // 要在路由组之前全局使用「跨域中间件」, 否则OPTIONS会返回404 func Cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method origin := c.Request.Header.Get("Origin") if origin != "" { c.Header("Access-Control-Allow-Origin", origin) c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization") c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type") c.Header("Access-Control-Allow-Credentials", "false") c.Set("content-type", "application/json") } if method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) return } c.Next() } } func TlsHandler() gin.HandlerFunc { return func(c *gin.Context) { secureMiddleware := secure.New(secure.Options{ SSLRedirect: true, SSLHost: ":443", }) err := secureMiddleware.Process(c.Writer, c.Request) if err != nil { c.Abort() return } c.Next() } }