リモートユーザーのIPアドレスを取得する方法がわかりません。
次のような単純なリクエストルートがあるとしましょう。
app.get(/, function (req, res){
var forwardedIpsStr = req.header('x-forwarded-for');
var IP = '';
if (forwardedIpsStr) {
IP = forwardedIps = forwardedIpsStr.split(',')[0];
}
});
実際のユーザーのIPアドレスを取得するには上記の方法は正しいですか。それとももっと良い方法がありますか。そしてプロキシはどうですか?
あなたがNGiNXのようなプロキシの後ろで走っているか、あるいはあなたが持っているものだけをやっているのであれば、あなたは 'x-forwarded-for'をチェックするべきです:
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
プロキシが「あなたの」ではない場合、偽造される可能性があるため、「x-forwarded-for」ヘッダーは信頼できません。
@alessioalexからの回答はうまくいきますが、 Express-guide の Express behind proxies のセクションで述べられているような別の方法があります。
app.enable('trust proxy')
を追加します。req.ip
またはreq.ips
を使用します。X-forwarded-forヘッダーで渡されたものすべてを信頼するよりも高度なものが必要で、信頼できないソースから既存のx-forwarded-forヘッダーを削除しない場合は、「信頼プロキシ」のオプションが増えます。詳細については、リンクされているガイドを参照してください。
注:req.connection.remoteAddress
は私のソリューションでは動作しません。
nginx.conf
ファイルで:proxy_set_header X-Real-IP $remote_addr;
node.js
サーバーファイルで:var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
小文字のヘッダーを表すことに注意してください
特にノードの場合、 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.remoteAddress
はreq.ip
よりも優れたアプローチであるが、他方はプロキシのIPアドレス(ある場合)。
それが、現在受け入れられている答えが示唆する理由です:
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
req.headers['x-forwarded-for']
は、エクスプレスreq.ip
と同等です。
app.set('trust proxy', true)
を追加req.ip
またはreq.ips
を使用するプロキシの背後にあるエクスプレス によると、req.ip
を正しく設定していれば、trust proxy
はリバースプロキシを考慮に入れています。したがって、ネットワーク層から取得され、プロキシを意識しないreq.connection.remoteAddress
よりも優れています。
このエクスプレスミドルウェアを使うだけです 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);
});
これは この答え に関する単なる追加情報です。
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にアクセスできるようになります。
Headersオブジェクトには必要なものがすべて揃っています。これを実行するだけです。
var ip = req.headers['x-forwarded-for'].split(',')[0];
これは私のために他よりよく働いた。私のサイトはCloudFlareの後ろにあり、それはcf-connecting-ip
を必要とするようでした。
req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress
このcf-connecting-ip
ヘッダについては何も言わなかったのでテストしませんでした プロキシの背後にある表現 .
私はこの質問が答えられたことを知っています、しかし、ここに私が働いてもらう方法があります。
let ip = req.connection.remoteAddress.split(`:`).pop();
var ip = req.connection.remoteAddress;
ip = ip.split( ':')[3];
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;
}