package middleware import ( "context" "fmt" "net/http" "one-api/common" "time" "github.com/gin-gonic/gin" ) const ( EmailVerificationRateLimitMark = "EV" EmailVerificationMaxRequests = 2 // 30秒内最多2次 EmailVerificationDuration = 30 // 30秒时间窗口 ) func redisEmailVerificationRateLimiter(c *gin.Context) { ctx := context.Background() rdb := common.RDB key := "emailVerification:" + EmailVerificationRateLimitMark + ":" + c.ClientIP() listLength, err := rdb.LLen(ctx, key).Result() if err != nil { fmt.Println("Redis限流检查失败:", err.Error()) c.Status(http.StatusInternalServerError) c.Abort() return } if listLength < EmailVerificationMaxRequests { rdb.LPush(ctx, key, time.Now().Format(timeFormat)) rdb.Expire(ctx, key, time.Duration(EmailVerificationDuration)*time.Second) c.Next() return } c.JSON(http.StatusTooManyRequests, gin.H{ "success": false, "message": fmt.Sprintf("发送过于频繁,请等待 %d 秒后再试", EmailVerificationDuration), }) c.Abort() } func memoryEmailVerificationRateLimiter(c *gin.Context) { key := EmailVerificationRateLimitMark + ":" + c.ClientIP() if !inMemoryRateLimiter.Request(key, EmailVerificationMaxRequests, EmailVerificationDuration) { c.JSON(http.StatusTooManyRequests, gin.H{ "success": false, "message": "发送过于频繁,请稍后再试", }) c.Abort() return } c.Next() } func EmailVerificationRateLimit() gin.HandlerFunc { return func(c *gin.Context) { if common.RedisEnabled { redisEmailVerificationRateLimiter(c) } else { inMemoryRateLimiter.Init(common.RateLimitKeyExpirationDuration) memoryEmailVerificationRateLimiter(c) } } }