为了账号安全,请及时绑定邮箱和手机立即绑定

从 http.Request 获取客户端 IP 地址的正确方法

从 http.Request 获取客户端 IP 地址的正确方法

Go
ibeautiful 2021-09-09 14:05:19
获取所有客户端 IP 地址的正确方法是http.Request什么?在PHP有很多的变数,我应该检查。在 Go 上也一样吗?我发现的一个是:req.RemoteAddr请求是否区分大小写?例如x-forwarded-for与X-Forwarded-For和相同X-FORWARDED-FOR?(来自req.Header.Get("X-FORWARDED-FOR"))
查看完整描述

3 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

查看http.Request您可以找到以下成员变量:


// HTTP defines that header names are case-insensitive.

// The request parser implements this by canonicalizing the

// name, making the first character and any characters

// following a hyphen uppercase and the rest lowercase.

//

// For client requests certain headers are automatically

// added and may override values in Header.

//

// See the documentation for the Request.Write method.

Header Header


// RemoteAddr allows HTTP servers and other software to record

// the network address that sent the request, usually for

// logging. This field is not filled in by ReadRequest and

// has no defined format. The HTTP server in this package

// sets RemoteAddr to an "IP:port" address before invoking a

// handler.

// This field is ignored by the HTTP client.

RemoteAddr string

您可以使用RemoteAddr获取远程客户端的 IP 地址和端口(格式为“IP:port”),这是原始请求者或最后一个代理(例如位于您的服务器前面的负载均衡器)的地址。


这就是你所拥有的一切。


然后您可以调查不区分大小写的标题(根据上面的文档),这意味着您的所有示例都将工作并产生相同的结果:


req.Header.Get("X-Forwarded-For") // capitalisation

req.Header.Get("x-forwarded-for") // doesn't

req.Header.Get("X-FORWARDED-FOR") // matter

这是因为内部http.Header.Get会为您规范密钥。(如果您想直接访问标头映射,而不是通过Get,则需要先使用http.CanonicalHeaderKey。)


最后,"X-Forwarded-For"可能是您想要查看的字段,以便获取有关客户端 IP 的更多信息。这在很大程度上取决于远程端使用的 HTTP 软件,因为客户端可以根据需要在其中放置任何内容。另请注意,此字段的预期格式是逗号+空格分隔的 IP 地址列表。您需要稍微解析一下以获得您选择的单个 IP(可能是列表中的第一个 IP),例如:


// Assuming format is as expected

ips := strings.Split("10.0.0.1, 10.0.0.2, 10.0.0.3", ", ")

for _, ip := range ips {

    fmt.Println(ip)

}

将产生:


10.0.0.1

10.0.0.2

10.0.0.3


查看完整回答
反对 回复 2021-09-09
?
DIEA

TA贡献1820条经验 获得超2个赞

这就是我想出IP的方式


func ReadUserIP(r *http.Request) string {

    IPAddress := r.Header.Get("X-Real-Ip")

    if IPAddress == "" {

        IPAddress = r.Header.Get("X-Forwarded-For")

    }

    if IPAddress == "" {

        IPAddress = r.RemoteAddr

    }

    return IPAddress

}

  • X-Real-Ip - 获取第一个真实 IP(如果请求位于多个 NAT 源/负载均衡器后面)

  • X-Forwarded-For - 如果由于某种原因 X-Real-Ip 为空白且不返回响应,则从 X-Forwarded-For 获取

  • 远程地址 - 最后的手段(通常不可靠,因为这可能是最后一个 ip 或者如果它是对服务器的裸 http 请求,即没有负载平衡器)


查看完整回答
反对 回复 2021-09-09
  • 3 回答
  • 0 关注
  • 496 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信