获取所有客户端 IP 地址的正确方法是http.Request什么?在PHP有很多的变数,我应该检查。在 Go 上也一样吗?
http.Request
PHP
我发现的一个是:
req.RemoteAddr
请求是否区分大小写?例如x-forwarded-for与X-Forwarded-For和相同X-FORWARDED-FOR?(来自req.Header.Get("X-FORWARDED-FOR"))
x-forwarded-for
X-Forwarded-For
X-FORWARDED-FOR
req.Header.Get("X-FORWARDED-FOR")
查看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”),这是原始请求者或最后一个代理(例如位于您的服务器前面的负载均衡器)的地址。
RemoteAddr
这就是你所拥有的一切。
然后您可以调查不区分大小写的标题(根据上面的文档),这意味着您的所有示例都将工作并产生相同的结果:
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。)
http.Header.Get
Get
最后,"X-Forwarded-For"可能是您想要查看的字段,以便获取有关客户端 IP 的更多信息。这在很大程度上取决于远程端使用的 HTTP 软件,因为客户端可以根据需要将任何内容放入其中。另请注意,此字段的预期格式是逗号+空格分隔的 IP 地址列表。您需要稍微解析一下以获得您选择的单个 IP(可能是列表中的第一个 IP),例如:
"X-Forwarded-For"
// 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