From b18059b45e85e75dbfecd0ae0d596e0f46e9f626 Mon Sep 17 00:00:00 2001 From: yaooort Date: Sat, 9 Oct 2021 20:26:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=99=90=E6=B5=81?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6=EF=BC=8C=E6=A0=B9=E6=8D=AEIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/config.yaml | 4 +++ server/config/system.go | 2 ++ server/middleware/limit_ip.go | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 server/middleware/limit_ip.go diff --git a/server/config.yaml b/server/config.yaml index 18454d82..a256df76 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -45,6 +45,10 @@ system: db-type: 'mysql' oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 use-multipoint: false + # IP限制次数 一个小时15000次 + iplimit-count: 15000 + # IP限制一个小时 + iplimit-time: 3600 # captcha configuration captcha: diff --git a/server/config/system.go b/server/config/system.go index 768788ab..8cf92b06 100644 --- a/server/config/system.go +++ b/server/config/system.go @@ -6,4 +6,6 @@ type System struct { DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"` // Oss类型 UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"` // 多点登录拦截 + LimitCountIP int `mapstructure:"iplimit-count" json:"iplimitCount" yaml:"iplimit-count"` + LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimitTime" yaml:"iplimit-time"` } diff --git a/server/middleware/limit_ip.go b/server/middleware/limit_ip.go new file mode 100644 index 00000000..21e66d2a --- /dev/null +++ b/server/middleware/limit_ip.go @@ -0,0 +1,53 @@ +package middleware + +import ( + "context" + "errors" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" + "github.com/gin-gonic/gin" + "time" +) + +// ip限制 +func IPLimit() gin.HandlerFunc { + return func(c *gin.Context) { + key := "RequestClientIPLimit===" + c.ClientIP() + limit := global.GVA_CONFIG.System.LimitCountIP + second := global.GVA_CONFIG.System.LimitTimeIP + expiration := time.Duration(second) * time.Second + if err := SetLimitWithTime(key, limit, expiration); err != nil { + response.FailWithMessage(err.Error(), c) + return + } + // 继续往下处理 + c.Next() + } +} + +// 设置访问次数 +func SetLimitWithTime(key string, limit int, expiration time.Duration) error { + count, err := global.GVA_REDIS.Exists(context.Background(), key).Result() + if err != nil || count == 0 { + pipe := global.GVA_REDIS.TxPipeline() + pipe.Incr(context.Background(), key) + pipe.Expire(context.Background(), key, expiration) + _, err := pipe.Exec(context.Background()) + return err + } else { + //次数 + if times, err := global.GVA_REDIS.Get(context.Background(), key).Int(); err != nil { + return err + } else { + if times >= limit { + if t, err := global.GVA_REDIS.PTTL(context.Background(), key).Result(); err != nil { + return errors.New("请求太过频繁,请稍后再试") + } else { + return errors.New("请求太过频繁, 请 " + t.String() + " 秒后尝试") + } + } else { + return global.GVA_REDIS.Incr(context.Background(), key).Err() + } + } + } +} From 52852e6ce2881785e6f03ba6a9f8dfcb536504a1 Mon Sep 17 00:00:00 2001 From: yaooort Date: Sat, 9 Oct 2021 20:37:28 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/middleware/limit_ip.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/middleware/limit_ip.go b/server/middleware/limit_ip.go index 21e66d2a..0e18cac9 100644 --- a/server/middleware/limit_ip.go +++ b/server/middleware/limit_ip.go @@ -18,6 +18,7 @@ func IPLimit() gin.HandlerFunc { expiration := time.Duration(second) * time.Second if err := SetLimitWithTime(key, limit, expiration); err != nil { response.FailWithMessage(err.Error(), c) + c.Abort() return } // 继续往下处理