You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gin框架时如何仅获取客户端的IPv4地址?

嘿,这个问题我碰到过好几次——明明服务只监听IPv4,gin却偶尔返回IPv6地址,对吧?别慌,咱们一步步解决:

为什么会出现这种情况?

虽然你明确用net.Listen("tcp4", ...)监听IPv4端口,但还是可能拿到IPv6地址,主要原因有两个:

  • 客户端通过IPv6过渡技术(比如NAT64、IPv6隧道)访问,请求会被转换成IPv6格式转发到你的IPv4服务;
  • 如果你的服务前端有反向代理/负载均衡,代理可能会把客户端的IPv6地址通过X-Forwarded-For这类请求头传递过来,而gin的ClientIP()会优先读取这些头的内容。
解决方案

根据你的场景,分两种情况处理:

情况1:无反向代理(直接监听IPv4)

直接对c.ClientIP()返回的地址做解析过滤,提取纯IPv4地址,尤其是处理常见的IPv4映射的IPv6地址(格式如::ffff:192.168.1.1):

web.POST("/path", func(c *gin.Context) {
    ipStr := c.ClientIP()
    // 解析IP地址
    ip := net.ParseIP(ipStr)
    if ip == nil {
        // 处理无效IP的场景,比如返回错误
        c.String(http.StatusBadRequest, "invalid IP address")
        return
    }

    // 提取IPv4地址:To4()会返回对应的IPv4(如果是IPv4或IPv4映射的IPv6),否则返回nil
    ipv4Addr := ip.To4()
    if ipv4Addr != nil {
        // 拿到了合法的IPv4地址
        c.String(http.StatusOK, "Client IPv4: %s", ipv4Addr.String())
    } else {
        // 纯IPv6地址,根据你的业务需求处理:比如记录日志、返回空或拒绝请求
        // 因为你的服务只监听IPv4,这种情况大概率是异常请求
        c.String(http.StatusBadRequest, "only IPv4 requests are allowed")
    }
})

情况2:有反向代理/负载均衡

如果你的服务前面有代理(比如Nginx、Cloudflare),需要先配置gin的信任代理列表,让ClientIP()正确识别真实客户端的IPv4地址,而不是代理的IPv6地址:

router := gin.Default()
// 设置信任的代理IP段(替换成你的代理服务器IPv4地址/段)
router.SetTrustedProxies([]string{"192.168.1.0/24", "10.0.0.0/8"})

// 然后处理请求
web.POST("/path", func(c *gin.Context) {
    ipStr := c.ClientIP()
    ip := net.ParseIP(ipStr)
    if ipv4Addr := ip.To4(); ipv4Addr != nil {
        // 使用提取的IPv4地址
    }
})
额外说明

你收到的那些纯IPv6地址(比如2402:800:xxxx:xxxx),大概率是客户端通过IPv6网络访问,但你的服务监听的是IPv4,这可能是因为你的服务器所在的网络支持IPv6过渡,或者客户端开启了IPv6优先。这种情况下,用上面的代码就能过滤掉纯IPv6,只保留合法的IPv4地址。

内容的提问来源于stack exchange,提问作者majidarif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:54:17