ホームページ  >  記事  >  バックエンド開発  >  golangでクライアントIPを取得するにはどうすればよいですか?

golangでクライアントIPを取得するにはどうすればよいですか?

coldplay.xixi
coldplay.xixiオリジナル
2020-06-20 10:13:305020ブラウズ

golangでクライアントIPを取得するにはどうすればよいですか?

Golang でクライアント IP を取得するにはどうすればよいですか?

Golang のクライアント IP 取得メソッド:

ClientIP メソッドは ClientPublicIP メソッドと似ていますが、http に従ってクライアント IP を取得する点が異なります。プロトコル合意。合意された形式に従ってパブリック IP アドレスを検索します。

複雑なネットワーク、サービス アーキテクチャ、ビジネス ロジックを備えた環境では、http プロトコルで合意された方法に従って実際の IP を取得できるとは限りません。当社のビジネスでは、ユーザー トラフィックは 3 者間で転送されます。複数のレベル (すべて (http クライアント) が 3 者自身によって実装されているため、必然的にいくつかの欠陥が存在します。現時点では、将来のサービスがユーザーの実際の IP を取得することはますます困難になるでしょう。あなたはそれさえ知りません)取得したIPが本物かどうか。

しかし、お客様のトラフィックは 3 者によって転送されるため、テストを除いてもほとんどのお客様はパブリック ネットワーク ユーザーです。ClientPublicIP メソッドと ClientIP メソッドを組み合わせることで、常にユーザーの実際の IP をより適切に取得できます。

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

上記の方法を使用すると、ユーザーの実際の IP アドレスを常に効果的に取得できます。2 つの方法の具体的な実装を分析してみましょう。

// 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 はまず、X-Forwarded-For ヘッダーの で区切られた最初の IP アドレスを読み取ります。このアドレスが存在しない場合は、X-Real-Ip から取得されます。ヘッダーを取得しても存在しない場合は、トラフィックがリバース プロキシによって転送されず、クライアントが直接サービスを要求したことを意味します。このとき、IP アドレスからポート番号を除いたものが http.Request を通じて傍受されます。 .RemoteAddr フィールド。

この方法は非常に簡単で、http 規約形式に従って取得するもので、X-Forwarded-For ヘッダーと X-Real-Ip ヘッダーは nginx や X-Real-Ip ヘッダーなどのリバース プロキシによって埋められます。ハプロキシ。

// 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 は非常に単純です。ClientIP メソッドの読み取り順序は同じです。X-Forwarded-For リストでパブリック ネットワーク IP を見つけようとするだけです。X-Real かどうかのチェックがない場合は、 -Ip はパブリック ネットワーク IP であり、次に http.Request.RemoteAddr がパブリック ネットワーク IP であるかどうかを確認します。パブリック ネットワーク IP が見つからない場合は、空の文字列が返されます。

この方法では、最初にユーザーのパブリック IP を取得する機会が得られ、多くの場合、パブリック IP の方が価値があります。

推奨チュートリアル: 「go 言語チュートリアル

以上がgolangでクライアントIPを取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。