Golang + Gin + Redis IP 限时拦截限制

原理

每次访问redis会记住IP地址为key,值为0。每次访问值就会加一,达到设定好的访问限制后就会返回403。直到60秒后redis缓存失效。

准备

  1. redis 安装就不再说明了,某度一下很简单。笔者使用的是某塔自带的redis,傻瓜安装。
  2. 安装Go的redis依赖。

文件树

├─main.go
└─middlewares
   └─middlewares.go

main.go

package main

import (
	"net/http"

	"./middlewares"
	"github.com/gin-gonic/gin"
	"github.com/thinkerou/favicon"
)

func main() {
    // 启动redis
	err := middlewares.InitClient()
	if err != nil {
		//redis连接错误
		panic(err)
	}
	fmt.Println("Redis连接成功")

	router := gin.Default()

    // 网站图标
	router.Use(favicon.New("./ay.ico"))

    // 防火墙中间件
	router.Use(middlewares.RateMiddleware)
    
    // 没有页面返回
	router.NoRoute(func(context *gin.Context) {
		context.IndentedJSON(http.StatusNotFound, gin.H{
			"code": 404,
			"data": "Page Not Found",
			"msg":  "https://api.y-alpha.com/",
		})
	})
    
    // 重定向
	router.GET("/", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "https://baidu.com/")
	})

    // 8080端口监听
	router.Run(":8080")

}

middlewares.go

package middlewares

import (
	"context"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
)

var redisDb *redis.Client

// 连接到redis
func InitClient() (err error) {
	redisDb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // redis地址
		Password: "",               // redis密码,没有则留空
		DB:       0,                // 默认数据库,默认是0
	})

	//通过 *redis.Client.Ping() 来检查是否成功连接到了redis服务器
	_, err = redisDb.Ping(context.TODO()).Result()
	if err != nil {
		return err
	}
	return nil
}

// 防火墙中间件
func RateMiddleware(c *gin.Context) {
    // 60 秒刷新key为IP(c.ClientIP())的r值为0
	err := redisDb.SetNX(context.TODO(), c.ClientIP(), 0, 60*time.Second).Err()

    // 每次访问,这个IP的对应的值加一
	redisDb.Incr(context.TODO(), c.ClientIP())
	if err != nil {
		panic(err)
	}
    
    // 获取IP访问的次数
	var val int
	val, err = redisDb.Get(context.TODO(), c.ClientIP()).Int()
	if err != nil {
		panic(err)
	}
    // 如果大于60次,返回403
	if val > 60 {
		c.Abort()
		c.JSON(http.StatusForbidden, gin.H{
			"code": 403,
			"data": "IP Ban, please try again later",
		})
		return
	} else {
        // 到下一个中间件
		c.Next()
	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值