345

リモートユーザーのIPアドレスを取得する方法が完全にはわかりません。

次のような単純なリクエストルートがあるとします。

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];  
   }
});

上記のアプローチは実際のユーザーのIPアドレスを取得するのに正しいですか、それともより良い方法がありますか?そして、プロキシはどうですか?

4

16 に答える 16

619

NGINX などのプロキシの背後で実行している場合は、次のことを確認する必要があります'x-forwarded-for'

var ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress 

プロキシが「あなたのもの」でない場合、'x-forwarded-for'なりすましの可能性があるため、ヘッダーを信頼しません。

于 2012-06-01T11:53:33.490 に答える
285

@alessioalexからの回答は機能しますが、 Expressのプロキシの背後にあるExpressのセクションで述べられている別の方法があります-ガイド

  1. app.set('trust proxy', true)Express初期化コードに追加します。
  2. リモートクライアントのIPを取得する場合は、req.ipまたはreq.ips通常の方法で(リバースプロキシがないかのように)使用します。

オプションの読み物:

  • req.ipまたはを使用しreq.ipsます。req.connection.remoteAddressこのソリューションでは機能しません。
  • 'trust proxy'ヘッダーで渡されるすべてのものを信頼するよりも高度なものが必要な場合x-forwarded-for(たとえば、プロキシが信頼できないソースから既存のx-forwarded-forヘッダーを削除しない場合)、より多くのオプションを使用できます。詳細については、リンクされたガイドを参照してください。
  • x-forwarded-forプロキシサーバーにヘッダーが設定され ていない場合は、2つの可能性があります。
    1. プロキシサーバーは、要求が最初にあった場所に関する情報を中継しません。この場合、リクエストが元々どこから来たのかを知る方法はありません。最初にプロキシサーバーの構成を変更する必要があります。
      • たとえば、リバースプロキシとしてnginxを使用する場合はproxy_set_header X-Forwarded-For $remote_addr;、構成に追加する必要がある場合があります。
    2. プロキシサーバーは、要求が元々どこから来たのかに関する情報を独自の方法で中継します(たとえば、カスタムhttpヘッダー)。そのような場合、この答えは機能しません。その情報を引き出すためのカスタムの方法があるかもしれませんが、最初にメカニズムを理解する必要があります。
于 2013-01-31T17:31:43.070 に答える
33

特にノードの場合、イベント接続の下のhttpサーバーコンポーネントのドキュメントには次のように記載されています。

[トリガー] 新しい TCP ストリームが確立されたとき。[The] socket は net.Socket 型のオブジェクトです。通常、ユーザーはこのイベントにアクセスしたくないでしょう。特に、プロトコルパーサーがソケットに接続する方法が原因で、ソケットは読み取り可能なイベントを発行しません。ソケットには からもアクセスできますrequest.connection

したがって、それはrequest.connectionソケットであることを意味し、ドキュメントによると、実際にはsocket.remoteAddress属性があり、ドキュメントによると次のとおりです。

リモート IP アドレスの文字列表現。たとえば、「74.125.127.100」または「2001:4860:a005::68」です。

Express では、リクエスト オブジェクトは Node http リクエスト オブジェクトのインスタンスでもあるため、このアプローチは引き続き機能します。

ただし、Express.js では、リクエストにはすでにreq.ipreq.ipsの 2 つの属性があります。

req.ip

リモートアドレスを返すか、「トラストプロキシ」が有効になっている場合はアップストリームアドレスを返します。

req.ips

「trust proxy」がの場合true、「X-Forwarded-For」IP アドレス リストを解析して配列を返します。それ以外の場合は、空の配列が返されます。たとえば、値が「クライアント、プロキシ 1、プロキシ 2」の場合、配列 [「クライアント」、「プロキシ 1」、「プロキシ 2」] を受け取ります。ここで、「プロキシ 2」は最も下流です。

私の理解によれば、 Expressreq.ipは よりも優れたアプローチであることに言及する価値があるかもしれません。実際のクライアント IP が含まれているreq.connection.remoteAddressためreq.ip(信頼できるプロキシが Express で有効になっている場合)、もう一方にはプロキシの IP アドレスが含まれている可能性があるためです (存在する場合)。 1)。

それが、現在受け入れられている回答が示唆する理由です。

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

req.headers['x-forwarded-for']express と同等ですreq.ip

于 2014-02-06T16:46:07.703 に答える
29

サードパーティのライブラリを使用しても問題ない場合。request-ipを確認できます。

あなたはそれを使用することができます

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

ソース コードはかなり長いので、ここではコピーしません。https://github.com/pbojinov/request-ip/blob/master/src/index.jsで確認できます。

基本的、

リクエスト内の特定のヘッダーを探し、存在しない場合はいくつかのデフォルトにフォールバックします。

ユーザー IP は、次の順序で決定されます。

  1. X-Client-IP
  2. X-Forwarded-For(ヘッダーは、「クライアント IP、プロキシ 1 IP、プロキシ 2 IP」の形式で複数の IP アドレスを返す場合があるため、最初の IP アドレスを取得します。)
  3. CF-Connecting-IP(クラウドフレア)
  4. Fastly-Client-Ip(クラウド関数に転送されると、CDN および Firebase ホスティング ヘッダーが高速になります)
  5. True-Client-Ip(アカマイと Cloudflare)
  6. X-Real-IP(Nginx プロキシ/FastCGI)
  7. X-Cluster-Client-IP(ラックスペース LB、リバーベッド スティングレイ)
  8. X-ForwardedForwarded-ForおよびForwarded(#2 のバリエーション)
  9. req.connection.remoteAddress
  10. req.socket.remoteAddress
  11. req.connection.socket.remoteAddress
  12. req.info.remoteAddress

IP アドレスが見つからない場合は、 が返されnullます。

開示: 私は図書館とは関係ありません。

于 2020-04-03T02:45:16.977 に答える
5

私はこの質問が答えられたことを知っていますが、これが私の仕事をする方法です。

let ip = req.connection.remoteAddress.split(`:`).pop();
于 2019-01-25T19:59:38.463 に答える
2

これは他のものよりもうまくいきました。私のサイトは CloudFlare の背後にあり、cf-connecting-ip.

req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress

このヘッダーについて何も言わなかったため、プロキシの背後で Express をテストしませんでした。cf-connecting-ip

于 2017-04-09T03:28:49.500 に答える