123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package middleware
- import (
- "fmt"
- "github.com/gin-gonic/gin"
- "go.uber.org/zap"
- "sfbase/global"
- sutils "sfbase/utils"
- "sfis/db"
- "sfis/lock"
- "sfis/model"
- "sfis/model/response"
- "sfis/utils"
- "strconv"
- "strings"
- "time"
- )
- 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
- )
- requestUrl = context.Request.URL.String()
- requestUrl = strings.Split(requestUrl, "?")[0]
- requestUrl = strings.Split(requestUrl, "/")[3]
- if p, ok := utils.ApiUrlCache.Load(requestUrl); ok {
- productID = p.(*model.Product).ID
- } else {
- response.FailWithDetailed(response.ParamError, nil, "url错误", context)
- context.Abort()
- return
- }
- 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()
- if now-_timestamp > 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白名单校验
- */
- if ipWhiteList != "*" {
- requestIp := utils.GetIp(context.Request)
- 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)
- if userLock := lock.GetUserLock(appID); userLock != nil {
- /**
- 第二步:用户接口产品校验-加锁处理
- */
- //2.1 取用户接口状态校验
- userLock.Lock()
- userProduct := &model.UserProduct{}
- db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID})
- userLock.Unlock()
- if userProduct.InterfaceStatus != 0 {
- response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口已停用", context)
- context.Abort()
- return
- }
- //2.2 取用户余量|账户余额 校验
- costModel := userProduct.CostModel
- product := utils.GetProductByID(productID)
- productType := product.ProductType
- userLock.Lock()
- switch costModel {
- case 0:
- //按剩余量扣费
- if productType == 0 {
- //按次扣费-每调一次 剩余量-1
- userProduct.LeftNum = userProduct.LeftNum - 1
- } else if productType == 1 {
- //按条扣费-每调一次剩余量-len(getDataList )
- }
- case 1:
- //按账户钱包余额扣费
- if productType == 0 {
- //按次扣费-每调一次
- //todo 账户余额表user_account的余额 减去 product单价*1
- } else if productType == 1 {
- //按条扣费-每调一次
- //todo 账户余额表user_account的余额 减去 product单价*len(getDataList)
- }
- case 2:
- //优先扣剩余量,剩余量为0,扣钱包余额
- }
- }
- }
- }
|