Documentation
¶
Index ¶
- Constants
- Variables
- func APIRateLimit() gin.HandlerFunc
- func APIRedisRateLimit() gin.HandlerFunc
- func AdminRequired() gin.HandlerFunc
- func AnyUserRequired() gin.HandlerFunc
- func AuthRequired() gin.HandlerFunc
- func CORS() gin.HandlerFunc
- func CORSForAPI() gin.HandlerFunc
- func CORSWithConfig(corsCfg *config.CORSConfig) gin.HandlerFunc
- func CORSWithOrigins(origins []string) gin.HandlerFunc
- func CORSWithWildcard() gin.HandlerFunc
- func CSRF(config ...CSRFConfig) gin.HandlerFunc
- func CSRFExempt() gin.HandlerFunc
- func CSRFForAPI() gin.HandlerFunc
- func CSRFToken(c *gin.Context)
- func CSRFWithExempt(config ...CSRFConfig) gin.HandlerFunc
- func CSRFWithSkip(skipPaths []string) gin.HandlerFunc
- func CustomRateLimit(rate int, window time.Duration) gin.HandlerFunc
- func CustomRedisRateLimit(keyPrefix string, rate int, window time.Duration, ...) gin.HandlerFunc
- func DoubleSubmitCookie() gin.HandlerFunc
- func GenerateAPIToken(c *gin.Context)
- func GetCSRFToken(c *gin.Context) string
- func GetRequestID(c *gin.Context) string
- func GetRole(c *gin.Context) string
- func GetUserID(c *gin.Context) uint
- func GetUserType(c *gin.Context) string
- func GetUsername(c *gin.Context) string
- func InitRateLimiters()
- func Logger() gin.HandlerFunc
- func LoggerForAPI() gin.HandlerFunc
- func LoggerForDebug() gin.HandlerFunc
- func LoggerMinimal() gin.HandlerFunc
- func LoggerWithConfig(cfg LoggerConfig) gin.HandlerFunc
- func LoginRateLimit() gin.HandlerFunc
- func LoginRedisRateLimit() gin.HandlerFunc
- func Metrics() gin.HandlerFunc
- func RateLimit(limiter *RateLimiter) gin.HandlerFunc
- func Recover() gin.HandlerFunc
- func RecoverWithDetail() gin.HandlerFunc
- func RedisRateLimit(keyPrefix string, rate int, opts ...RedisRateLimiterOption) gin.HandlerFunc
- func RedisRateLimitWithIdentifier(keyPrefix string, rate int, identifierFunc func(c *gin.Context) string, ...) gin.HandlerFunc
- func RequestID() gin.HandlerFunc
- func RequireAuth(checker AuthChecker, messages ...string) gin.HandlerFunc
- func RequireRoles(roles ...string) gin.HandlerFunc
- func RequireUserTypes(userTypes ...string) gin.HandlerFunc
- func StaffRequired() gin.HandlerFunc
- func StopRateLimiters()
- func SuperAdminRequired() gin.HandlerFunc
- func Timeout(d time.Duration) gin.HandlerFunc
- func UploadRateLimit() gin.HandlerFunc
- func UploadRedisRateLimit() gin.HandlerFunc
- type AuthChecker
- type AuthUser
- type CSRFConfig
- type LoggerConfig
- type RateLimitRegistry
- func (r *RateLimitRegistry) APIRateLimit() gin.HandlerFunc
- func (r *RateLimitRegistry) CustomRateLimit(rate int, window time.Duration) gin.HandlerFunc
- func (r *RateLimitRegistry) Init()
- func (r *RateLimitRegistry) LoginRateLimit() gin.HandlerFunc
- func (r *RateLimitRegistry) Stop()
- func (r *RateLimitRegistry) UploadRateLimit() gin.HandlerFunc
- type RateLimiter
- type RedisRateLimiter
- func (rl *RedisRateLimiter) Allow(ctx context.Context, identifier string) (bool, error)
- func (rl *RedisRateLimiter) GetCount(ctx context.Context, identifier string) (int64, error)
- func (rl *RedisRateLimiter) Reset(ctx context.Context, identifier string) error
- func (rl *RedisRateLimiter) SetFailClosed(failClosed bool)
- type RedisRateLimiterOption
Constants ¶
const ( // ContextKeyUserID 用户ID上下文键 ContextKeyUserID = "user_id" // ContextKeyUsername 用户名上下文键 ContextKeyUsername = "username" // ContextKeyRole 角色上下文键 ContextKeyRole = "role" // ContextKeyUserType 用户类型上下文键 ContextKeyUserType = "user_type" // DefaultUserTypeSuperAdmin 默认超级管理员用户类型 DefaultUserTypeSuperAdmin = "super_admin" // DefaultUserTypeAdmin 默认管理员用户类型 DefaultUserTypeAdmin = "admin" // DefaultUserTypeStaff 默认员工用户类型 DefaultUserTypeStaff = "staff" )
const ( // CSRFTokenLength CSRF Token 长度 CSRFTokenLength = 32 // CSRFHeaderName CSRF Header 名称 CSRFHeaderName = "X-CSRF-Token" // CSRFCookieName CSRF Cookie 名称 CSRFCookieName = "csrf_token" // CSRFFormField 表单字段名称 CSRFFormField = "_csrf" // CSRFMaxBodyBytes JSON body 中读取 CSRF token 的最大字节数,防止 pre-auth OOM。 CSRFMaxBodyBytes = 1 << 20 // 1 MiB )
Variables ¶
var ( // fail-closed 限流器在此情况下拒绝请求;fail-open 限流器放行。 ErrRedisRateLimiterUnavailable = errors.New("redis rate limiter: redis client unavailable") // ErrRedisRateLimiterUnexpectedResult Redis 返回非预期的结果类型(非 int64)。 // fail-closed 限流器拒绝;fail-open 限流器放行。旧实现裸断言会 panic。 ErrRedisRateLimiterUnexpectedResult = errors.New("redis rate limiter: unexpected result type") )
H4c: Redis 限流器故障相关错误。
var DefaultCSRFConfig = CSRFConfig{ TokenLength: CSRFTokenLength, HeaderName: CSRFHeaderName, CookieName: CSRFCookieName, FormField: CSRFFormField, Secure: false, HTTPOnly: true, SameSite: http.SameSiteLaxMode, Path: "/", MaxAge: 3600, MaxBodyBytes: CSRFMaxBodyBytes, ErrorFunc: defaultCSRFError, SkipFunc: nil, }
DefaultCSRFConfig 默认 CSRF 配置
var DefaultLoggerConfig = LoggerConfig{ LogRequestBody: false, LogResponseBody: false, MaxBodyLength: 1024, SkipPaths: []string{"/health", "/swagger"}, SkipPathPrefixes: []string{"/public", "/static"}, SlowRequestThreshold: 500 * time.Millisecond, }
DefaultLoggerConfig 默认日志配置
Functions ¶
func APIRedisRateLimit ¶
func APIRedisRateLimit() gin.HandlerFunc
APIRedisRateLimit API Redis 分布式限流(fail-open,避免影响业务)。
func AnyUserRequired ¶
func AnyUserRequired() gin.HandlerFunc
AnyUserRequired 任意用户权限中间件(默认允许 admin/super_admin/staff)
func CORS ¶
func CORS() gin.HandlerFunc
CORS 跨域中间件 支持从配置文件读取 CORS 配置;遵循 W3C CORS 规范: 当 AllowCredentials=true 时,Access-Control-Allow-Origin 必须回显为具体 Origin, 不能使用 "*"(浏览器会拒绝携带凭证的响应)。
func CORSWithConfig ¶
func CORSWithConfig(corsCfg *config.CORSConfig) gin.HandlerFunc
CORSWithConfig 使用自定义配置的 CORS 中间件
func CORSWithOrigins ¶
func CORSWithOrigins(origins []string) gin.HandlerFunc
CORSWithOrigins 使用指定域名列表的 CORS 中间件
func CORSWithWildcard ¶
func CORSWithWildcard() gin.HandlerFunc
CORSWithWildcard 允许所有来源的 CORS 中间件(仅用于开发环境) 注意:生产环境不建议使用
func CSRFForAPI ¶
func CSRFForAPI() gin.HandlerFunc
CSRFForAPI 适用于 API 的 CSRF 中间件(不使用 Cookie) 客户端需要先调用 GenerateAPIToken 获取 Token,随后在每个非安全方法请求的 X-CSRF-Token 头中携带。Token 单次消费(验证通过即删除)且受 TTL 约束, 防止重放与内存无限增长。
注意:存储为进程内内存,仅适用于单实例部署。多实例请自行用 Redis SETEX + GETDEL 实现等价语义。
func CSRFToken ¶
CSRFToken 返回当前请求上下文中的 CSRF Token;若上下文无 Token 则现场生成一个返回。 适用于 Cookie/双重提交模式(与 CSRF/DoubleSubmitCookie 中间件配合), 不与 CSRFForAPI 配套--API 模式的可校验 Token 请用 GenerateAPIToken 颁发。
func CSRFWithExempt ¶
func CSRFWithExempt(config ...CSRFConfig) gin.HandlerFunc
CSRFWithExempt 支持 exempt 标记的 CSRF 中间件
func CSRFWithSkip ¶
func CSRFWithSkip(skipPaths []string) gin.HandlerFunc
CSRFWithSkip 跳过指定路径的 CSRF 检查
func CustomRateLimit ¶
func CustomRateLimit(rate int, window time.Duration) gin.HandlerFunc
CustomRateLimit 自定义速率限制(内存版)。限流器在首次请求时创建并登记到当前默认 Registry(供 Stop 统一停止,避免 cleanup goroutine 泄漏,H4b)。
func CustomRedisRateLimit ¶
func CustomRedisRateLimit(keyPrefix string, rate int, window time.Duration, opts ...RedisRateLimiterOption) gin.HandlerFunc
CustomRedisRateLimit 自定义 Redis 分布式限流。 默认 fail-open,传 WithFailClosed(true) 切换为 fail-closed。
func DoubleSubmitCookie ¶
func DoubleSubmitCookie() gin.HandlerFunc
DoubleSubmitCookie 双重提交 Cookie 模式(无需服务器存储) 适用于无状态 API
func GenerateAPIToken ¶
GenerateAPIToken 生成 API CSRF Token(用于 API 模式) 颁发的 Token 写入进程内存储,供 CSRFForAPI 校验。
func LoggerWithConfig ¶
func LoggerWithConfig(cfg LoggerConfig) gin.HandlerFunc
LoggerWithConfig 使用自定义配置的日志中间件
func LoginRateLimit ¶
func LoginRateLimit() gin.HandlerFunc
LoginRateLimit 登录接口速率限制。限流器在首次请求时从当前默认 Registry 懒创建, 故 App.Init swap 后用的是 App 的 Registry(避免 pre-Init 注册到 init Registry 被丢弃)。
func LoginRedisRateLimit ¶
func LoginRedisRateLimit() gin.HandlerFunc
LoginRedisRateLimit 登录接口 Redis 分布式限流(fail-closed)。
H4c: 登录防爆破场景必须 fail-closed--Redis 故障时若 fail-open 则限流失效、 攻击者可借 Redis 抖动窗口无限爆破。改为 fail-closed:Redis 故障时返 503 拒绝。
func Metrics ¶ added in v1.1.0
func Metrics() gin.HandlerFunc
Metrics Prometheus 指标中间件(#18)。记录请求计数、耗时、在飞数。 route 标签用 c.FullPath()(路由模板,如 /api/v1/users/:id),避免高基数。
func RateLimit ¶
func RateLimit(limiter *RateLimiter) gin.HandlerFunc
RateLimit 通用速率限制中间件(内存版,用户自持 limiter 时使用)。
func RecoverWithDetail ¶
func RecoverWithDetail() gin.HandlerFunc
RecoverWithDetail panic恢复中间件(详细版本,返回更多信息) 注意: 生产环境不应使用,会暴露敏感信息
func RedisRateLimit ¶
func RedisRateLimit(keyPrefix string, rate int, opts ...RedisRateLimiterOption) gin.HandlerFunc
RedisRateLimit Redis 分布式限流中间件。 默认 fail-open(Redis 故障时放行,避免影响业务);安全敏感场景(登录防爆破等) 传 WithFailClosed(true),Redis 故障时拒绝以防限流失效。
func RedisRateLimitWithIdentifier ¶
func RedisRateLimitWithIdentifier(keyPrefix string, rate int, identifierFunc func(c *gin.Context) string, opts ...RedisRateLimiterOption) gin.HandlerFunc
RedisRateLimitWithIdentifier 自定义标识的 Redis 分布式限流。 参数: keyPrefix 键名前缀,rate 1 分钟窗口内允许的请求数,identifierFunc 标识获取函数。 identifierFunc 为 nil 或返回空串时回退到 c.ClientIP()。默认 fail-open,传 WithFailClosed(true) 切换。
func RequestID ¶
func RequestID() gin.HandlerFunc
RequestID 请求ID中间件,为每个请求生成唯一ID便于追踪。
客户端可经 X-Request-ID 头传入 ID 用于链路串联,但会做校验(M15 修复): 仅接受可见 ASCII、无换行、长度 ≤128 的值,否则忽略并重新生成——防头注入与日志伪造。
func RequireAuth ¶
func RequireAuth(checker AuthChecker, messages ...string) gin.HandlerFunc
RequireAuth 自定义权限中间件
func RequireUserTypes ¶
func RequireUserTypes(userTypes ...string) gin.HandlerFunc
RequireUserTypes 用户类型权限中间件
func StopRateLimiters ¶
func StopRateLimiters()
StopRateLimiters 停止默认 Registry 的所有限流器。注意:仅停默认 Registry-- App 持自己的 Registry 时应在 Shutdown 调 app 自己的 Stop(Phase 5)。
func Timeout ¶ added in v1.1.0
func Timeout(d time.Duration) gin.HandlerFunc
Timeout 请求级超时中间件(#19)。
与 http.Server.ReadTimeout(连接级)不同,这是业务级超时: 为每个请求的 context 设置 deadline,下游 GORM / Redis / HTTP 调用 走 c.Request.Context() 即可级联取消,避免单个慢请求拖垮协程。
⚠️ 软超时语义(M14 文档化):本中间件仅注入带 deadline 的 ctx,不会主动中断 handler。 生效前提是下游实际消费 ctx——GORM/Redis/HTTP 客户端等会响应 ctx 取消;但若 handler 是纯 CPU 循环、阻塞于不查 ctx 的调用、或不读 c.Request.Context(),则 deadline 到期 也不会停。需要硬中断的场景请配合 http.Server.WriteTimeout 或在 handler 内显式 select ctx.Done。
用法:
r.Use(middleware.Timeout(5 * time.Second))
d <= 0 时不启用超时(直接 Next)。
func UploadRedisRateLimit ¶
func UploadRedisRateLimit() gin.HandlerFunc
UploadRedisRateLimit 上传接口 Redis 分布式限流(fail-closed)。 上传属资源敏感操作,Redis 故障时拒绝以防限流静默失效。
Types ¶
type CSRFConfig ¶
type CSRFConfig struct {
// TokenLength Token 长度
TokenLength int
// HeaderName Header 名称
HeaderName string
// CookieName Cookie 名称
CookieName string
// FormField 表单字段名
FormField string
// Secure Cookie 是否启用 Secure
Secure bool
// HTTPOnly Cookie 是否启用 HttpOnly
HTTPOnly bool
// SameSite Cookie SameSite 属性
SameSite http.SameSite
// Domain Cookie 域名
Domain string
// Path Cookie 路径
Path string
// MaxAge Cookie 有效期(秒)
MaxAge int
// SessionCookie 为 true 时显式使用会话 Cookie(MaxAge=0)。
// 为保持 CSRFWithConfig(CSRFConfig{}) 的默认行为,MaxAge=0 且本字段为 false 时仍使用默认 1 小时。
SessionCookie bool
// MaxBodyBytes 从 JSON body 提取 token 时允许读取的最大字节数。
// <=0 时使用默认 1MiB。Header/Form token 不受此限制。
MaxBodyBytes int64
// ErrorFunc 错误处理函数
ErrorFunc func(c *gin.Context)
// SkipFunc 跳过检查函数
SkipFunc func(c *gin.Context) bool
}
CSRFConfig CSRF 配置
type LoggerConfig ¶
type LoggerConfig struct {
// LogRequestBody 是否记录请求体
LogRequestBody bool
// LogResponseBody 是否记录响应体
LogResponseBody bool
// MaxBodyLength 最大记录的请求/响应体长度(字节)
MaxBodyLength int
// SkipPaths 不记录日志的路径
SkipPaths []string
// SkipPathPrefixes 不记录日志的路径前缀
SkipPathPrefixes []string
// SlowRequestThreshold 慢请求阈值(超过此时间记录警告)
SlowRequestThreshold time.Duration
}
LoggerConfig 日志中间件配置
type RateLimitRegistry ¶ added in v1.4.0
type RateLimitRegistry struct {
// contains filtered or unexported fields
}
RateLimitRegistry 持一组内存限流器,支持 per-App 隔离。
func GetDefaultRateLimitRegistry ¶ added in v1.4.0
func GetDefaultRateLimitRegistry() *RateLimitRegistry
GetDefaultRateLimitRegistry 返回全局默认 Registry。
func NewRateLimitRegistry ¶ added in v1.4.0
func NewRateLimitRegistry() *RateLimitRegistry
NewRateLimitRegistry 创建限流器注册表实例。
func SwapDefaultRateLimitRegistry ¶ added in v1.4.0
func SwapDefaultRateLimitRegistry(r *RateLimitRegistry) *RateLimitRegistry
SwapDefaultRateLimitRegistry 置为全局默认,返回被替换的旧(照 Swap 模式)。nil 忽略,返回当前默认。
func (*RateLimitRegistry) APIRateLimit ¶ added in v1.4.0
func (r *RateLimitRegistry) APIRateLimit() gin.HandlerFunc
APIRateLimit 返回绑定到此 Registry 的普通 API 限流中间件。
func (*RateLimitRegistry) CustomRateLimit ¶ added in v1.4.0
func (r *RateLimitRegistry) CustomRateLimit(rate int, window time.Duration) gin.HandlerFunc
CustomRateLimit 返回绑定到此 Registry 的自定义限流中间件。limiter 在首次请求时创建并 登记到此 Registry(r.registerCustom),由 App.Shutdown 的 registry.Stop() 收口,无泄漏。
func (*RateLimitRegistry) Init ¶ added in v1.4.0
func (r *RateLimitRegistry) Init()
Init 预初始化标准限流器(可选;不调则首次请求时懒创建)。先停旧的同名限流器释放 goroutine。
func (*RateLimitRegistry) LoginRateLimit ¶ added in v1.4.0
func (r *RateLimitRegistry) LoginRateLimit() gin.HandlerFunc
LoginRateLimit 返回绑定到此 Registry 的登录限流中间件。
func (*RateLimitRegistry) Stop ¶ added in v1.4.0
func (r *RateLimitRegistry) Stop()
Stop 停止注册表中所有限流器(释放 cleanup goroutine)。幂等。
func (*RateLimitRegistry) UploadRateLimit ¶ added in v1.4.0
func (r *RateLimitRegistry) UploadRateLimit() gin.HandlerFunc
UploadRateLimit 返回绑定到此 Registry 的上传限流中间件。
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter 速率限制器(内存版,单实例使用)
func NewRateLimiter ¶
func NewRateLimiter(rate int, window time.Duration) *RateLimiter
NewRateLimiter 创建速率限制器(内存版)。 rate<=0 或 window<=0 时 panic。内部启动 cleanup goroutine,调用方负责在不再使用时 调用 (*RateLimiter).Stop 释放,否则 goroutine 泄漏。
func (*RateLimiter) Allow ¶
func (rl *RateLimiter) Allow(ip string) bool
Allow 检查是否允许请求。
固定窗口语义(H4a 修复):windowStart 是当前窗口起点,仅在窗口过期重置时变更; 放行时不再更新 windowStart。窗口内 count 达到 rate 即拒绝,窗口过期则重置为新窗口。 旧实现每次放行更新 lastSeen,致重置分支对持续客户端永不成立、稳态客户端被误限流。
注意:固定窗口算法允许窗口边界突发(两窗口交界处瞬时可达 2×rate)。 如需平滑限流(无突发),请用 Redis 版 RedisRateLimiter(滑动窗口)。
func (*RateLimiter) SetNowFunc ¶ added in v1.2.0
func (rl *RateLimiter) SetNowFunc(f func() time.Time)
SetNowFunc 注入时间源(默认 time.Now),供测试用可控时钟验证窗口语义。 生产代码通常无需调用。
type RedisRateLimiter ¶
type RedisRateLimiter struct {
// contains filtered or unexported fields
}
RedisRateLimiter Redis 分布式限流器
func NewRedisRateLimiter ¶
func NewRedisRateLimiter(keyPrefix string, rate int, window time.Duration, opts ...RedisRateLimiterOption) *RedisRateLimiter
NewRedisRateLimiter 创建 Redis 分布式限流器。 默认 fail-open(Redis 故障时放行,避免影响业务);安全敏感场景传 WithFailClosed(true)。
func (*RedisRateLimiter) Allow ¶
Allow 检查是否允许请求。
H4c 修复:
- result.(int64) 改 comma-ok,断言失败返 ErrRedisRateLimiterUnexpectedResult 而非 panic。
- Redis 错误/断言失败时按 failClosed 策略决定:fail-closed 返 (false, err) 拒绝, fail-open 返 (true, err) 放行(兼容旧行为)。中间件层据此 allowed 值决定放行/拒绝, 不再无条件 fail-open--登录防爆破等安全场景用 fail-closed 限流器即可在 Redis 故障时拒绝。
Redis 未启用(redisClient() == nil)时:fail-closed 返 (false, ErrRedisRateLimiterUnavailable), fail-open 返 (true, nil)(兼容旧行为)。安全场景必须确保 Redis 已启用。
Phase 5:redisClient() 注入优先、全局兜底,App 经 WithRedisClient 注入 per-App client。
func (*RedisRateLimiter) Reset ¶
func (rl *RedisRateLimiter) Reset(ctx context.Context, identifier string) error
Reset 重置限流计数
func (*RedisRateLimiter) SetFailClosed ¶ added in v1.2.0
func (rl *RedisRateLimiter) SetFailClosed(failClosed bool)
SetFailClosed 设置 Redis 故障时的策略:true=拒绝(安全型),false=放行(兼容默认)。 供已创建的限流器切换策略。并发安全(atomic.Store),可与并发 Allow 调用共存。
type RedisRateLimiterOption ¶ added in v1.3.0
type RedisRateLimiterOption func(*RedisRateLimiter)
RedisRateLimiterOption 配置 RedisRateLimiter 的可选策略。
func WithFailClosed ¶ added in v1.3.0
func WithFailClosed(failClosed bool) RedisRateLimiterOption
WithFailClosed 设置 Redis 故障时 fail-closed(拒绝请求)。 不传或传 false 为 fail-open(放行,兼容默认)。安全敏感场景(登录防爆破等)应传 true。
func WithRedisClient ¶ added in v1.4.0
func WithRedisClient(client *redis.Client) RedisRateLimiterOption
WithRedisClient 注入指定 Redis 客户端(Phase 5,多 Redis/测试隔离)。 不传则回退 database.GetRedis()(全局)。App 可经 app.RedisClient() 取自身 client 注入。