package middleware import ( "fmt" "sfbase/global" sutils "sfbase/utils" "sfis/model/response" "sfis/utils" "strconv" "strings" "time" "github.com/gin-gonic/gin" "go.uber.org/zap" ) const TimestampExpireTime = 600 //单位秒,header里的时间戳超时时间 10分钟 func TokenAuth() gin.HandlerFunc { return func(context *gin.Context) { var ( requestUrl string token string timestamp string appID string productID int requestIP string ) requestUrl = context.Request.URL.String() global.Logger.Info(requestUrl) requestUrl = strings.Split(requestUrl, "v1")[1] global.Logger.Info(requestUrl) // a := strings.Split(requestUrl, "/") // requestUrl = a[4] if p, ok := utils.ApiUrlCache.Load(requestUrl); ok { productID = p.(int) } else { response.FailWithDetailed(response.ParamError, nil, "url错误", context) context.Abort() return } // productID = 1000 token = context.Request.Header.Get("token") timestamp = context.Request.Header.Get("timestamp") appID = context.PostForm("app_id") if appID == "" || token == "" || timestamp == "" { response.FailWithDetailed(response.ParamEmpty, nil, "参数缺失或为空", context) context.Abort() return } _timestamp, err := strconv.ParseInt(timestamp, 10, 64) if err != nil { response.FailWithDetailed(response.ParamError, nil, "参数异常", context) context.Abort() return } now := time.Now().Unix() TimestampExpire := now - _timestamp if TimestampExpire < 0 { TimestampExpire = -TimestampExpire } if TimestampExpire > TimestampExpireTime { //token时间验证 十分钟 response.FailWithDetailed(response.TokenExpired, nil, "签名过期", context) context.Abort() return } user := utils.GetUserByAppID(appID) secretKey := user.SecretKey ipWhiteList := user.IpWhiteList userName := user.Name global.Logger.Info("用户:", zap.Any("userName:", userName), zap.Any("appID:", appID), zap.Any("secretKey:", secretKey), zap.Any("ipWhiteList:", ipWhiteList)) /** 第一步:ip白名单校验 */ requestIP = utils.GetIp(context.Request) if ipWhiteList != "*" { if strings.Index(ipWhiteList, requestIP) < 0 { response.FailWithDetailed(response.IpInvalid, nil, "ip不在白名单", context) context.Abort() return } } /** 第二步:MD5签名校验 */ signToken := sutils.MD5(fmt.Sprintf("%s%s%s", appID, timestamp, user.SecretKey)) if token != signToken { response.FailWithDetailed(response.TokenInvalid, nil, "身份验证失败", context) context.Abort() return } context.Set("appID", appID) context.Set("productID", productID) context.Set("requestIP", requestIP) } }