41 lines
1.1 KiB
Go
41 lines
1.1 KiB
Go
package middleware
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/freefire/jiang13-bbs/service"
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// RateLimitMiddleware 速率限制中间件(按 IP)
|
||
func RateLimitMiddleware(rl *service.RateLimiter, rateType string) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
key := rateType + ":" + c.ClientIP()
|
||
if !rl.Allow(key) {
|
||
c.Header("Retry-After", "60")
|
||
c.AbortWithStatusJSON(http.StatusTooManyRequests, gin.H{"error": "请求过于频繁,请稍后再试"})
|
||
return
|
||
}
|
||
c.Next()
|
||
}
|
||
}
|
||
|
||
// RateLimitUserMiddleware 按登录用户限流(需挂在 RequireAuth 之后)
|
||
func RateLimitUserMiddleware(rl *service.RateLimiter, rateType string) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
claims := CurrentUser(c)
|
||
id := "anon"
|
||
if claims != nil {
|
||
id = strconv.FormatUint(uint64(claims.ID), 10)
|
||
}
|
||
key := rateType + ":u:" + id
|
||
if !rl.Allow(key) {
|
||
c.Header("Retry-After", "60")
|
||
c.AbortWithStatusJSON(http.StatusTooManyRequests, gin.H{"error": "操作过于频繁,请稍后再试"})
|
||
return
|
||
}
|
||
c.Next()
|
||
}
|
||
}
|