web-dev-qa-db-ja.com

Express.js:リモートクライアントアドレスを取得する方法

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

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

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

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

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

201
Erik

あなたがNGiNXのようなプロキシの後ろで走っているか、あるいはあなたが持っているものだけをやっているのであれば、あなたは 'x-forwarded-for'をチェックするべきです:

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

プロキシが「あなたの」ではない場合、偽造される可能性があるため、「x-forwarded-for」ヘッダーは信頼できません。

378
alessioalex

@alessioalexからの回答はうまくいきますが、 Express-guide Express behind proxies のセクションで述べられているような別の方法があります。

  1. 高速初期化コードにapp.enable('trust proxy')を追加します。
  2. リモートクライアントのIPを取得したい場合は、(リバースプロキシが存在しない場合と同様に)通常の方法でreq.ipまたはreq.ipsを使用します。

X-forwarded-forヘッダーで渡されたものすべてを信頼するよりも高度なものが必要で、信頼できないソースから既存のx-forwarded-forヘッダーを削除しない場合は、「信頼プロキシ」のオプションが増えます。詳細については、リンクされているガイドを参照してください。

注:req.connection.remoteAddressは私のソリューションでは動作しません。

201
Haozhun

nginx.confファイルで:
proxy_set_header X-Real-IP $remote_addr;

node.jsサーバーファイルで:
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

小文字のヘッダーを表すことに注意してください

50
ququzone

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

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

つまり、request.connectionはソケットであり、ドキュメントによると socket.remoteAddress 属性があり、ドキュメントによると:

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

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

ただし、Express.jsでは、リクエストにはすでに2つの属性があります: req.ip および req.ips

req.ip

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

req.ips

"trust proxy"trueの場合、 "X-Forwarded-For" IPアドレスリストを解析して配列を返します。そうでない場合は空の配列が返されます。たとえば、値が「client、proxy1、proxy2」の場合、「[client」、「proxy1」、「proxy2」]という配列を受け取ります。「proxy2」は最も下流です。

私の理解によれば、req.ipには実際のクライアントIPが含まれているので(エクスプレスで信頼されたプロキシが有効になっている場合)、エクスプレスreq.connection.remoteAddressreq.ipよりも優れたアプローチであるが、他方はプロキシのIPアドレス(ある場合)。

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

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

req.headers['x-forwarded-for']は、エクスプレスreq.ipと同等です。

27
Edwin Dalorzo
  1. app.set('trust proxy', true)を追加
  2. 通常の方法でreq.ipまたはreq.ipsを使用する
6
Bald

プロキシの背後にあるエクスプレス によると、req.ipを正しく設定していれば、trust proxyはリバースプロキシを考慮に入れています。したがって、ネットワーク層から取得され、プロキシを意識しないreq.connection.remoteAddressよりも優れています。

3
abbr

このエクスプレスミドルウェアを使うだけです https://www.npmjs.com/package/express-ip

あなたが使用してモジュールをインストールすることができます

npm i express-ip

使用法

const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);

app.get('/', function (req, res) {
    console.log(req.ipInfo);
});
2
Oyetoke Tobi

これは この答え に関する単なる追加情報です。

nginxを使用している場合は、サイトのロケーションブロックにproxy_set_header X-Real-IP $remote_addr;を追加します。例えば/etc/nginx/sites-available/www.example.com。これがサーバーブロックの例です。

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.1.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $Host;
        proxy_cache_bypass $http_upgrade;
    }
}

nginxを再起動すると、node/expressアプリケーションルートのreq.headers['x-real-ip'] || req.connection.remoteAddress;でipにアクセスできるようになります。

2
learnsomemore

Headersオブジェクトには必要なものがすべて揃っています。これを実行するだけです。

var ip = req.headers['x-forwarded-for'].split(',')[0];
1
Juan David Arce

これは私のために他よりよく働いた。私のサイトはCloudFlareの後ろにあり、それはcf-connecting-ipを必要とするようでした。

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

このcf-connecting-ipヘッダについては何も言わなかったのでテストしませんでした プロキシの背後にある表現 .

1
ile

私はこの質問が答えられたことを知っています、しかし、ここに私が働いてもらう方法があります。

let ip = req.connection.remoteAddress.split(`:`).pop();
1
Lorem Ipsum

var ip = req.connection.remoteAddress;

ip = ip.split( ':')[3];

0
Bhulawat Ajay

Could-flare、nginx、およびx-real-ipのサポート

var user_ip;

    if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
      let first = req.headers['cf-connecting-ip'].split(', ');
      user_ip = first[0];
    } else {
      let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }
0
kakopappa