在 Gin 框架中实现 IP 白名单,可以通过中间件的方式检查客户端的 IP 地址是否在白名单中。如果不在白名单中,返回拒绝访问的响应。以下是实现教程:
实现步骤
-
定义 IP 白名单
创建一个列表存储允许访问的 IP 地址。 -
编写中间件
创建一个 Gin 中间件,用于拦截请求并检查客户端 IP 是否在白名单中。 -
应用中间件
在路由中注册中间件,使其作用于需要限制的路由。
示例代码
package main
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
// 定义 IP 白名单
var whitelist = []string{
"127.0.0.1", // 本地 IP
"192.168.1.100", // 示例局域网 IP
}
// 检查 IP 是否在白名单中
func isAllowedIP(clientIP string) bool {
for _, ip := range whitelist {
if clientIP == ip {
return true
}
}
return false
}
// IP 白名单中间件
func IPWhitelistMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
clientIP := c.ClientIP() // 获取客户端 IP 地址
if !isAllowedIP(clientIP) {
c.JSON(http.StatusForbidden, gin.H{
"message": "Forbidden: Your IP is not allowed",
})
c.Abort() // 中止请求
return
}
c.Next() // 继续处理请求
}
}
func main() {
r := gin.Default()
// 使用 IP 白名单中间件
r.Use(IPWhitelistMiddleware())
// 定义测试路由
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080") // 启动服务
}
测试步骤
-
启动服务
启动服务,监听8080
端口。 -
访问接口
- 使用允许的 IP(如本地
127.0.0.1
)访问http://localhost:8080/ping
。
响应:{ "message": "pong" }
- 使用不在白名单的 IP 访问,返回:
{ "message": "Forbidden: Your IP is not allowed" }
- 使用允许的 IP(如本地
说明
-
动态配置白名单
如果白名单需要动态配置,可以将其存储在配置文件或数据库中,并定期刷新到内存中。 -
支持 CIDR 格式
如果需要支持 IP 段,可以使用第三方库,如github.com/yl2chen/cidranger
来检查 IP 是否属于某个段。 -
多层代理支持
如果服务部署在反向代理之后,获取客户端真实 IP 时需要使用X-Forwarded-For
或X-Real-IP
,Gin 的c.ClientIP()
方法会自动处理这些头部信息。 -
安全性注意
IP 白名单适合简单的安全需求,但对于更复杂的场景(如高并发或分布式),推荐结合认证和权限系统。