Home  >  Article  >  Backend Development  >  How to get client ip in golang?

How to get client ip in golang?

coldplay.xixi
coldplay.xixiOriginal
2020-06-20 10:13:305007browse

How to get client ip in golang?

How to get the client IP in golang?

Golang's method of obtaining the client ip:

The ClientIP method is similar to the ClientPublicIP method, except that it obtains the client ip according to the http protocol agreement. Find the public IP address according to the agreed format.

In an environment with complex network and service architecture and business logic, it is not always possible to obtain the real IP according to the method agreed in the http protocol. In our business, user traffic is forwarded through three parties at multiple levels (all (http client) implemented by the three parties themselves, there will inevitably be some flaws. At this time, it will be more and more difficult for future services to obtain the user's real IP. You don't even know whether the IP you obtained is real.

But our customers’ traffic is forwarded by three parties, so most of the customers are public network users even excluding the test. Combining the ClientPublicIP and ClientIP methods can always better obtain the user’s real IP.

// var r *http.Request
ip := exnet.ClientPublicIP(r)
if ip == ""{
  ip = exnet.ClientIP(r)
}

Using the above method can always effectively obtain the user’s real IP address. Let’s analyze the specific implementation of the two methods.

// ClientIP 尽最大努力实现获取客户端 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。
func ClientIP(r *http.Request) string {
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
}
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
}
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
return ip
}
return ""
}

ClientIP first reads the first ip address separated by, in the X-Forwarded-For header. If this address does not exist, it will be retrieved from the X-Real-Ip header. Obtain, if it still does not exist, it means that the traffic is not forwarded by the reverse proxy, but the client directly requests the service. At this time, the IP address minus the port number is intercepted through the http.Request.RemoteAddr field.

This method is very simple, it is to obtain it according to the http convention format, where the X-Forwarded-For and X-Real-Ip headers are filled in by a reverse proxy, such as nginx or haproxy.

// ClientPublicIP 尽最大努力实现获取客户端公网 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。
func ClientPublicIP(r *http.Request) string {
var ip string
for _, ip = range strings.Split(r.Header.Get("X-Forwarded-For"), ",") {
ip = strings.TrimSpace(ip)
if ip != "" && !HasLocalIPddr(ip) {
return ip
}
}
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" && !HasLocalIPddr(ip) {
return ip
}
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
if !HasLocalIPddr(ip) {
return ip
}
}
return ""
}

ClientPublicIP is very simple. The reading order of the ClientIP method is the same. It just tries to find a public network ip in the X-Forwarded-For list. If there is no check whether X-Real-Ip is a public network ip , and secondly check whether http.Request.RemoteAddr is a public network IP. If the public network IP is not found, an empty string is returned.

This method allows us to have the opportunity to obtain the user's public IP first, and often the public IP is more valuable to us.

Recommended tutorial: "go language tutorial"

The above is the detailed content of How to get client ip in golang?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn