package middleware import ( "fmt" "nl-video-api/utility/response" "time" "github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" ) // RateLimit 限流中间件 func RateLimit(maxRequests int, window time.Duration) func(r *ghttp.Request) { return func(r *ghttp.Request) { var ( ctx = r.Context() client = g.Redis() key = fmt.Sprintf("rate_limit:%s", r.GetClientIp()) ) // 获取当前请求次数 count, err := client.Get(ctx, key) if err != nil { g.Log().Error(ctx, "Redis获取失败:", err) r.Middleware.Next() return } // 检查是否超过限制 if count.Int() >= maxRequests { response.Error(r, response.CodeError, "请求过于频繁,请稍后再试") return } // 增加计数 if count.Int() == 0 { // 第一次请求,设置过期时间 seconds := int64(window.Seconds()) client.Set(ctx, key, 1, gredis.SetOption{ TTLOption: gredis.TTLOption{EX: &seconds}, }) } else { // 增加计数 client.Incr(ctx, key) } r.Middleware.Next() } } // APIRateLimit API接口限流(每分钟60次) func APIRateLimit(r *ghttp.Request) { RateLimit(60, time.Minute)(r) } // LoginRateLimit 登录接口限流(每分钟5次) func LoginRateLimit(r *ghttp.Request) { RateLimit(5, time.Minute)(r) }