| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- 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)
- }
- }
- }
|