chore: release server-v1.0.62
Deploy Server / release-deploy-server (push) Successful in 51s

服务端安全加固:多维限流(按 IP/按门店)+ 敏感接口独立速率上限抵御 DDoS/刷接口;
登录暴力破解新增按来源 IP 锁定;反代后正确识别真实客户端 IP;
门店 custom_fields 轻量配置(录入默认值)透传保存。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
This commit is contained in:
wangjia
2026-06-19 20:20:44 +08:00
parent 0d967e899a
commit 7bbc944ae2
14 changed files with 628 additions and 57 deletions
+38 -12
View File
@@ -8,16 +8,17 @@ import (
)
type Config struct {
Server ServerConfig
Database DatabaseConfig
JWT JWTConfig
Storage StorageConfig
Session SessionConfig
Server ServerConfig
Database DatabaseConfig
JWT JWTConfig
Storage StorageConfig
Session SessionConfig
RateLimit RateLimitConfig
}
type ServerConfig struct {
Port string `mapstructure:"port"`
Mode string `mapstructure:"mode"` // debug | release
Mode string `mapstructure:"mode"` // debug | release
CORSOrigin string `mapstructure:"cors_origin"` // 允许的 CORS 来源,生产设为具体域名
}
@@ -35,12 +36,27 @@ type JWTConfig struct {
// SessionConfig 登录会话与并发限制(全局默认,可被每店 session_policy 覆盖)。
type SessionConfig struct {
LimitDesktop int `mapstructure:"limit_desktop"` // 桌面端(win/mac/linux)最大并发会话,0=禁止
LimitMobile int `mapstructure:"limit_mobile"` // 移动端(android/ios)最大并发会话,0=禁止
LimitWeb int `mapstructure:"limit_web"` // web 端最大并发会话,0=禁止
MaxFailures int `mapstructure:"max_failures"` // 连续登录失败几次后锁定
LockMinutes int `mapstructure:"lock_minutes"` // 锁定时长(分钟
RetentionDays int `mapstructure:"retention_days"` // 已撤销/过期会话与失败登录记录的保留天数,过期后台清理
LimitDesktop int `mapstructure:"limit_desktop"` // 桌面端(win/mac/linux)最大并发会话,0=禁止
LimitMobile int `mapstructure:"limit_mobile"` // 移动端(android/ios)最大并发会话,0=禁止
LimitWeb int `mapstructure:"limit_web"` // web 端最大并发会话,0=禁止
MaxFailures int `mapstructure:"max_failures"` // 同一账号连续登录失败几次后锁定
IPMaxFailures int `mapstructure:"ip_max_failures"` // 同一 IP 跨账号累计失败几次后锁定该 IP(防单 IP 撞多账号
LockMinutes int `mapstructure:"lock_minutes"` // 锁定时长(分钟)
RetentionDays int `mapstructure:"retention_days"` // 已撤销/过期会话与失败登录记录的保留天数,过期后台清理
}
// RateLimitConfig 应用层限流(按真实客户端 IP / 按门店)。各 *PerMin 为每分钟允许次数,
// burst 取同值(允许一分钟额度的突发,之后按速率回补)。Enabled=false 时所有限流放行。
type RateLimitConfig struct {
Enabled bool `mapstructure:"enabled"`
LoginPerMin int `mapstructure:"login_per_min"` // 未鉴权 /auth/login,按 IP
RefreshPerMin int `mapstructure:"refresh_per_min"` // 未鉴权 /auth/refresh,按 IP
RegisterPerMin int `mapstructure:"register_per_min"` // 未鉴权 /public/register,按 IP
ErrorsPerMin int `mapstructure:"errors_per_min"` // 未鉴权 /public/errors,按 IP
ShopListPerMin int `mapstructure:"shop_list_per_min"` // 公开商品列表(主爬取入口),按 IP,最紧
PublicReadPerMin int `mapstructure:"public_read_per_min"` // 其余公开读接口(单品/release),按 IP
ShopRPS int `mapstructure:"shop_rps"` // 认证流量每店每秒,按 shop_id
ShopBurst int `mapstructure:"shop_burst"` // 认证流量每店突发
}
type StorageConfig struct {
@@ -80,8 +96,18 @@ func Load() {
viper.SetDefault("session.limit_mobile", 2)
viper.SetDefault("session.limit_web", 2) // 默认不禁 web(官网挂着 Web 版 app);设 0 可禁
viper.SetDefault("session.max_failures", 5)
viper.SetDefault("session.ip_max_failures", 20)
viper.SetDefault("session.lock_minutes", 15)
viper.SetDefault("session.retention_days", 90)
viper.SetDefault("ratelimit.enabled", true)
viper.SetDefault("ratelimit.login_per_min", 10)
viper.SetDefault("ratelimit.refresh_per_min", 20)
viper.SetDefault("ratelimit.register_per_min", 5)
viper.SetDefault("ratelimit.errors_per_min", 30)
viper.SetDefault("ratelimit.shop_list_per_min", 30)
viper.SetDefault("ratelimit.public_read_per_min", 60)
viper.SetDefault("ratelimit.shop_rps", 20)
viper.SetDefault("ratelimit.shop_burst", 40)
viper.SetDefault("database.max_idle_conns", 10)
viper.SetDefault("database.max_open_conns", 100)
viper.SetDefault("storage.upload_dir", "./uploads/images")