首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >echo 解析客户端IP的坑clientIp

echo 解析客户端IP的坑clientIp

作者头像
golangLeetcode
发布2022-08-02 19:20:38
发布2022-08-02 19:20:38
1.2K0
举报

某些场景我们需要获取客户端的ip,比如埋点、反作弊、审计等等

代码语言:javascript
复制
ip := net.ParseIP(ctx.ClientIP())
ip = ip.To4()
ipInt32 := binary.BigEndian.Uint32(ip)

上面这段代码乍看没有问题,但是实际应用中可能panic

我们来看下echo中相关函数的实现,先从X-Forwarded-For中获取第一跳的ip地址,如果获取不到,就尝试从X-Real-Ip里获取

代码语言:javascript
复制
func (c *Context) ClientIP() string {
  if c.engine.ForwardedByClientIP {
    clientIP := c.requestHeader("X-Forwarded-For")
    clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0])
    if clientIP == "" {
      clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip"))
    }
    if clientIP != "" {
      return clientIP
    }
  }

这里直接通过逗号分隔X-Forwarded-For,取第一个字符串,众所周知X-Forwarded-For是可以篡改的,如果用户不遵守代理协议,把第一个ip地址写成非法的ip地址,比如一个字符串,那么这个函数返回的就是一个字符串

接下来我们看看解析ip的函数

代码语言:javascript
复制
// ParseIP parses s as an IP address, returning the result.
// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
// If s is not a valid textual representation of an IP address,
// ParseIP returns nil.
func ParseIP(s string) IP {
  for i := 0; i < len(s); i++ {
    switch s[i] {
    case '.':
      return parseIPv4(s)
    case ':':
      return parseIPv6(s)
    }
  }
  return nil
}

我们可以看到对于不合法的ip地址,返回的直接是个nil

代码语言:javascript
复制
// To4 converts the IPv4 address ip to a 4-byte representation.
// If ip is not an IPv4 address, To4 returns nil.
func (ip IP) To4() IP {
  if len(ip) == IPv4len {
    return ip
  }
  if len(ip) == IPv6len &&
    isZeros(ip[0:10]) &&
    ip[10] == 0xff &&
    ip[11] == 0xff {
    return ip[12:16]
  }
  return nil
}

转换函数也一样,如果不是合法的ipv4 或者ipv6地址,那么返回的仍然是个nil

如何修复呢

1,代码加nil判断

2,接入成对X-Forwarded-For 清洗

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档