409

ASP.NET で IP アドレスを取得する必要Request.UserHostAddressがありますが、これは通常、ユーザーの ISP の IP アドレスであり、たとえばリンクをクリックしたユーザーのマシンの IP アドレスではありません。実際の IP アドレスを取得するにはどうすればよいですか?

たとえば、スタック オーバーフローのユーザー プロファイルでは、「最後のアカウント アクティビティ: 86.123.127.8 から 4 時間前」ですが、マシンの IP アドレスは少し異なります。Stack Overflow はこのアドレスをどのように取得しますか?

一部の Web システムでは、目的のために IP アドレス チェックが行われます。たとえば、特定の IP アドレスの場合、24 時間ごとに、ユーザーはダウンロード リンクを 5 回しかクリックできないでしょうか? この IP アドレスは一意である必要があり、膨大な範囲のクライアントまたはインターネット ユーザーを持つ ISP 用ではありません。

よくわかりましたか?

4

21 に答える 21

478

多くの場合、あなたの Web サイトを訪れた人の IP アドレスを知りたいと思うでしょう。ASP.NET にはこれを行うための方法がいくつかありますが、これまで見てきた最良の方法の 1 つは、ServerVariables コレクションの "HTTP_X_FORWARDED_FOR" を使用することです。

これが理由です...

訪問者がプロキシ サーバーまたはルーターの背後にいる場合があり、標準Request.UserHostAddressではプロキシ サーバーまたはルーターの IP アドレスのみがキャプチャされます。この場合、ユーザーの IP アドレスはサーバー変数 ("HTTP_X_FORWARDED_FOR") に格納されます。

したがって、最初に「HTTP_X_FORWARDED_FOR」をチェックし、それが空の場合は単純に を返しServerVariables("REMOTE_ADDR")ます。

この方法は絶対確実というわけではありませんが、より良い結果につながる可能性があります。以下は、 James Crowley のブログ投稿「Gotcha: HTTP_X_FORWARDED_FOR が複数の IP アドレスを返す」から引用した VB.NET の ASP.NET コードです。

C#

protected string GetIPAddress()
{
    System.Web.HttpContext context = System.Web.HttpContext.Current; 
    string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

    if (!string.IsNullOrEmpty(ipAddress))
    {
        string[] addresses = ipAddress.Split(',');
        if (addresses.Length != 0)
        {
            return addresses[0];
        }
    }

    return context.Request.ServerVariables["REMOTE_ADDR"];
}

VB.NET

Public Shared Function GetIPAddress() As String
    Dim context As System.Web.HttpContext = System.Web.HttpContext.Current
    Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    If String.IsNullOrEmpty(sIPAddress) Then
        Return context.Request.ServerVariables("REMOTE_ADDR")
    Else
        Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})
        Return ipArray(0)
    End If
End Function
于 2009-04-11T17:03:57.243 に答える
147

他の人が言ったように、あなたが求めていることはできません。あなたが解決しようとしている問題を説明すれば、誰かが助けてくれるでしょうか?

例えば

  • ユーザーを一意に識別しようとしていますか?
  • IP アドレスの代わりに、Cookie またはセッション ID を使用できますか?

編集サーバーに表示されるアドレスは、ISPのアドレスであってはなりません.あなたが言うように、それは巨大な範囲になるでしょう. ブロードバンドのホーム ユーザーのアドレスはルーターのアドレスになるため、家の中のすべてのデバイスは外部からは同じように見えますが、ルーターは NAT を使用して、トラフィックが各デバイスに正しくルーティングされるようにします。オフィス環境からアクセスするユーザーの場合、アドレスはすべてのユーザーで同じである可能性があります。ID に IP アドレスを使用するサイトは、非常に間違ったものになるリスクがあります。あなたが挙げた例は良い例ですが、失敗することがよくあります。たとえば、私のオフィスは英国にあり、ブレークアウト ポイント (インターネット上にあるように見える場所) は、主要な IT 施設がある別の国にあるため、私のオフィスからは、私の IP アドレスは英国にないように見えます。このため、英国のみの Web コンテンツにアクセスできません。BBC iPlayer など)。私の会社には常に、同じ IP アドレスから Web にアクセスしているように見える何百人、あるいは何千人もの人がいます。

サーバー コードを書いているときは、表示されている IP アドレスが何を参照しているのかを決して確信することはできません。一部のユーザーはこの方法を好みます。一部の人々は、意図的にプロキシまたは VPN を使用して、さらに混乱させます。

マシンのアドレスが StackOverflow に表示される IP アドレスと異なると言う場合、どのようにしてマシンのアドレスを見つけているのでしょうか? ローカルで使用しているだけの場合、ipconfigまたはそのようなものを探している場合は、上記で概説した理由により異なると予想されます。外の世界が何を考えているかを再確認したい場合は、whatismyipaddress.com/をご覧ください。

NAT に関するこのウィキペディアのリンクは、これに関する背景を提供します。

于 2009-04-09T18:37:14.883 に答える
88

更新: Bruno Lopes に感謝します。複数の IP アドレスが来る可能性がある場合は、次の方法を使用する必要があります。

    private string GetUserIP()
    {
        string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (!string.IsNullOrEmpty(ipList))
        {
            return ipList.Split(',')[0];
        }

        return Request.ServerVariables["REMOTE_ADDR"];
    }
于 2012-03-05T13:27:49.943 に答える
26

もしc#がこのように見えるなら、非常に簡単です

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? 
                   Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
于 2013-01-30T14:41:08.617 に答える
25

ユーザーの IP アドレスについて他に何を考えますか? ネットワーク アダプターの IP アドレスが必要な場合は、残念ながら Web アプリでそれを行う方法はありません。ユーザーが NAT などの背後にいる場合、IP も取得できません。

更新: IP を使用してユーザーを制限する Web サイト (rapidshare など) がありますが、NAT 環境では正しく動作しません。

于 2009-04-09T18:21:15.330 に答える
23

私の経験を皆さんと共有する必要があると思います。状況によっては、REMOTE_ADDRでは探しているものが得られないことがあります。たとえば、舞台裏にロード バランサーがあり、クライアントの IP を取得しようとしている場合、問題が発生します。IP マスキング ソフトウェアで確認したほか、別の大陸にいる同僚にも確認しました。だからここに私の解決策があります。

クライアントの IP を知りたい場合は、すべての可能な証拠を選択して、それらが一意であるかどうかを判断できるようにします。

ここで、クライアント側の正確な IP を取得したい場合に役立つ別のサーバー変数を見つけました。だから私は使用しています: HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IPは常にクライアントの正確な IP を取得します。いずれにせよ、値が得られない場合は、 HTTP_X_FORWARDED_FORを探す必要があります。これは、クライアント IP を取得するための 2 番目に最適な候補であり、次に、IP を返す場合と返さない場合があるREMOTE_ADDR変数ですが、これらすべてを持っている私にとっては3つが、それらを監視するのに最適だと私が見つけたものです。

これが一部の人に役立つことを願っています。

于 2012-11-15T16:27:24.317 に答える
16

以下を使用できます。

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();
于 2011-09-27T00:20:23.867 に答える
14

IP アドレスは、「7 層スタック」のネットワーク層の一部です。ネットワーク層は、IP アドレスでやりたいことは何でもできます。これは、プロキシ サーバー、NAT、リレーなどで発生することです。

アプリケーション層は、決して IP アドレスに依存すべきではありません。特に、IP アドレスは、ネットワーク接続の一方の端の識別子以外のものの識別子であることを意図していません。接続が閉じられるとすぐに、(同じユーザーの) IP アドレスが変更されることを予期する必要があります。

于 2009-04-09T18:32:25.193 に答える
9
string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
于 2014-07-15T07:38:15.493 に答える
7

できることは、ユーザーのルーター IP と転送された IP を保存し、[外部パブリックと内部プライベート] の両方の IP を使用して信頼できるようにすることです。ただし、数日後、クライアントにルーターから新しい内部 IP が割り当てられる可能性がありますが、信頼性が高くなります。

于 2011-08-04T15:22:47.123 に答える
-3

これを使って

Dns.GetHostEntry(Dns.GetHostName())
于 2012-09-09T09:39:02.780 に答える
-7

試す:

using System.Net;

public static string GetIpAddress()  // Get IP Address
{
    string ip = "";     
    IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());
    IPAddress[] addr = ipEntry.AddressList;
    ip = addr[2].ToString();
    return ip;
}
public static string GetCompCode()  // Get Computer Name
{   
    string strHostName = "";
    strHostName = Dns.GetHostName();
    return strHostName;
}
于 2013-07-30T14:56:35.417 に答える