You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/api/middleware/ratelimit.go

46 lines
943 B
Go

// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-03-04 16:08:06
// Distributed under terms of the MIT license.
package middleware
import (
"fmt"
"time"
"github.com/veypi/vbase/libs/cache"
"github.com/veypi/vigo"
)
// RateLimiter 限流中间件
func RateLimiter(requests int, window time.Duration) func(*vigo.X) error {
return func(x *vigo.X) error {
// 获取标识优先用户ID其次IP
identifier := ""
if uid, ok := x.Get("user_id").(string); ok && uid != "" {
identifier = uid
} else {
identifier = x.GetRemoteIP()
}
key := fmt.Sprintf("ratelimit:%s:%s", identifier, x.Request.URL.Path)
count, err := cache.Incr(key)
if err != nil {
// Redis未启用跳过限流
return nil
}
// 第一次请求设置过期时间
if count == 1 {
cache.Expire(key, window)
}
if count > int64(requests) {
return vigo.ErrForbidden.WithString("rate limit exceeded")
}
return nil
}
}