- 新增管理端板块管理页面与后端接口(admin_board) - 新增旧版数据导入:legacyimport 服务、导入面板、importusers 命令行工具 - 聊天用户卡片、板块图标等 UI 组件与界面优化 - 补充 about/公告/1Panel 部署等文档 - gitignore 排除 dist/ 构建产物与 .agents/ 本地工具目录
55 lines
1.5 KiB
Go
55 lines
1.5 KiB
Go
package middleware
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/freefire/jiang13-bbs/model"
|
||
"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()
|
||
}
|
||
}
|
||
|
||
// StaffExempt 内容类频控豁免:管理角色直接放行,其余走原限流。
|
||
// 必须挂在 RequireAuth 之后(依赖 CurrentUser);角色变更会递增
|
||
// token_version 强制重登,故 JWT 内 role 可视为实时。
|
||
func StaffExempt(inner gin.HandlerFunc) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
if claims := CurrentUser(c); claims != nil && model.IsStaff(model.Role(claims.Role)) {
|
||
c.Next()
|
||
return
|
||
}
|
||
inner(c)
|
||
}
|
||
}
|