Files
mce/internal/middleware/ratelimit.go
Victor_Jay 55c408d86c fix: 审计问题全量修复 + RateLimiter 原子化重构 + CDN 本地化收紧
- 安全:移除 CSP 中 esm.sh/cdnjs.cloudflare.com,highlight.js 主题已本地化 73 个文件
- 安全:StatusBanned 分支补 dummy hash 防时序攻击
- 安全:手写 constantTimeEq 替换为 crypto/subtle.ConstantTimeCompare
- Bug:锁定操作消息已删除→已锁定
- YAGNI:删除 12 个空预留模板目录
- KISS:删除 common.CheckPassword 薄封装,统一用 bcrypt 调用
- KISS:删除 tokenCtrl 别名字段,api.go 统一用 authCtrl
- RateLimiter:check()+recordFail 闭包模式重构为 try() 原子操作,消除竞态
- RateLimiter:新增 ClearIP() 方法,注册成功时清除 IP 计数
- 文档:修正 audit_service.go 注释编号跳跃(3→5→4)
- 文档:修正 deps_core.go 过清理→过期清理
2026-05-31 11:13:32 +08:00

35 lines
1.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import "sync"
// RateLimiter 双维度滑动窗口登录限流
// 维度一(账户):同邮箱 1 分钟内失败 3 次 → 锁定 1 分钟
// 维度二IP同 IP 1 分钟内失败 10 次 → 锁定 1 分钟
type RateLimiter struct {
mu sync.RWMutex
accountFailures map[string]*windowState
ipFailures map[string]*windowState
}
// NewRateLimiter 创建限流器并启动后台清理
func NewRateLimiter() *RateLimiter {
rl := &RateLimiter{
accountFailures: make(map[string]*windowState),
ipFailures: make(map[string]*windowState),
}
go rl.cleanupLoop()
return rl
}
// AllowAccount 原子检查+递增帐户维度。未被封禁则递增失败计数并返回允许。
// 调用方在操作成功(如登录成功)时应调用 Clear 清除计数。
func (rl *RateLimiter) AllowAccount(email string) RateLimitResult {
return rl.try(rl.accountFailures, email, accountWindow, accountBlockDur, accountMaxFails, true)
}
// AllowIP 原子检查+递增 IP 维度。未被封禁则递增失败计数并返回允许。
// 调用方在操作成功时应调用 Clear 清除计数。
func (rl *RateLimiter) AllowIP(ip string) RateLimitResult {
return rl.try(rl.ipFailures, ip, ipWindow, ipBlockDur, ipMaxFails, false)
}