九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、Express
開発を進めてきてはや数カ月が経ち、いくつも「できない → 解決」を体験してきました。
そしてそんな中でも、「うっ、、言われてみれば当たり前ですよね・・・」という内容があったのでここで備忘録的に記事をつくっておきたいと思います。
その内容は、というと・・・
ExpressでIPアドレスが 「::ffff:127.0.0.1」しか取得できない😫
というものです。
これは、Express
+ nginx
で運用する場合のちょっとした罠(笑)のようなものなのですが、メインの開発を長年PHP
でやってきた私は、きっちりこの罠にハマってしまいました。。
ということで、今回は皆さんが私のように罠にハマらないよう、Express
+ nginx
でIPアドレスを取得する方法をご紹介します。
ぜひ皆さんのお役に立てると嬉しいです😊✨
※解決法に急ぐ場合 → 実際に解決する方法
開発環境: Node 8、Express 4.1、Ubuntu 18.04
何が原因なのか??
あるドメインでExpress
を運用する場合、以下のようになっていると思います。
- ブラウザからアクセス
- nginx を中継
- Expressにアクセス
これは、Express
だけで起動すると、
http://localhost:5000
というURL
になるので、ドメインを使う場合は、以下のようにExpress
へ「転送」する処理が必要になってくるためです。
server { listen 80; server_name express.test; location / { proxy_pass http://localhost:5000; } }
しかし、IPアドレスがうまく取得できない問題点はまさにここにあります。
つまり、PHP
の場合はnginxが
直接ウェブサーバーになりますが、Expressの場合は代理人としてアクセスするため、そのままだとnginx
のIPアドレスが取得されてしまうというわけです。
つまり、::ffff:127.0.0.1
は、nginx
(自分のサーバー)のことだったわけですね。
問題を解決する方法論
これまでは、nginx
が代理人だったのでIPアドレスは「::ffff:127.0.0.1」で固定でしたが、nginx
にはIPアドレスを変数として使える機能があります。
そのため、この変数を特定のヘッダーに追加することで、あたかもIPアドレスを「水バケツリレー」することができるわけです。
- ブラウザからアクセス
- nginx を中継(IPアドレスをヘッダーに追加)
- Express内で、そのヘッダーからIPアドレスを取得する
では、次からは実際の作業をご紹介します!
実際に解決する方法
ここからは実際にアクセスした人のIPアドレスを取得する方法をご説明します。
※私の環境はUbuntu 18.04
ですが、CentOS
などを使っている場合はファイルのパスを適宜変更してください。
nginxのコンフィグを変更する
まず以下のコマンドでnginxの設定を変更します。
sudo vi /etc/nginx/sites-available/default
そして、「X-Forwarded-For」にIPアドレスをセットします。
server { listen 80; server_name express.test; location / { proxy_pass http://localhost:5000; proxy_set_header X-Forwarded-For $remote_addr; } }
そして:wq!
などで保存したら、以下のコマンドでnginx
を再起動しましょう。
sudo systemctl restart nginx
これでnginx
側の作業は完了です。
nginxから送信されたIPアドレスを取得する
続いてExpress
側のコードです。
といっても、req
からヘッダー情報を取得するだけでOKです。
app.get('/ip', (req, res) => { const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; res.send(ip); });
なお、req.connection.remoteAddress
は「x-forwarded-for」が存在しない(つまり、ドメイン以外でアクセスされた)場合の保険のようなものです。
そして、ドメイン以外のアクセスの場合、req.headers['x-forwarded-for']
からIPアドレスを取得しようとしてもundefined
が返ってきます。
おわりに
ということで、今回は「Express + nginx」でIPアドレスが固定されてしまう場合の解決法をお届けしました。
冒頭でも書きましたが、nginx
が間にはさまっているので、IPアドレスがうまく取得できないのも当然の話ですよね。やっぱり固定概念で動こうとすると罠にハマってしまいやすいです💦
私の場合、これのせいで数時間無駄にしてしまいましたが、この記事で皆さんの時間をショートカットさせることができたら嬉しいです。
ではでは〜!