从 http.Request 获取客户端 IP 地址的正确方法 [英] Correct way of getting Client's IP Addresses from http.Request

查看:64
本文介绍了从 http.Request 获取客户端 IP 地址的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

http.Request 获取所有客户端 IP 地址的正确方法是什么?在PHP 中有很多变量 我应该检查一下.在 Go 上也一样吗?

What's the correct way to get all client's IP Addresses from http.Request? In PHP there are a lot of variables that I should check. Is it the same on Go?

我发现的一个是:

req.RemoteAddr

请求是否区分大小写?例如 x-forwarded-forX-Forwarded-ForX-FORWARDED-FOR 一样吗?(来自 req.Header.Get("X-FORWARDED-FOR"))

And is the request case sensitive? for example x-forwarded-for is the same as X-Forwarded-For and X-FORWARDED-FOR? (from req.Header.Get("X-FORWARDED-FOR"))

推荐答案

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

Looking at http.Request you can find the following member variables:

// 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"),即原始请求者或最后一个代理的地址(例如位于服务器前面的负载平衡器).

You can use RemoteAddr to get the remote client's IP address and port (the format is "IP:port"), which is the address of the original requestor or the last proxy (for example a load balancer which lives in front of your server).

这就是你所拥有的一切.

This is all you have for sure.

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

Then you can investigate the headers, which are case-insensitive (per documentation above), meaning all of your examples will work and yield the same result:

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 首先.)

This is because internally http.Header.Get will normalise the key for you. (If you want to access header map directly, and not through Get, you would need to use http.CanonicalHeaderKey first.)

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

Finally, "X-Forwarded-For" is probably the field you want to take a look at in order to grab more information about client's IP. This greatly depends on the HTTP software used on the remote side though, as client can put anything in there if it wishes to. Also, note the expected format of this field is the comma+space separated list of IP addresses. You will need to parse it a little bit to get a single IP of your choice (probably the first one in the list), for example:

// 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

这篇关于从 http.Request 获取客户端 IP 地址的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆