Webシステムを開発している中で、クライアントのIPアドレスを取得する必要がある場合があると思います。
CakePHPを使用し、クライアントのIPアドレスを取得するにはどのようになるのか調べてみました。
CakePHP1系〜3系それぞれののコントローラでのクライアントのIPアドレスの取得の方法です。
CakePHP3系の場合のみモデルでのIPアドレスの取得の方法を記載しています。
CakePHP 3系
//in controller $ip = $this->request->clientIp(); //in model $ip = Router::getRequest()->clientIp();
CakePHP 2系
//in controller $ip = $this->request->ClientIp();
CakePHP 1系
//in controller $ip = RequestHandlerComponent::getClientIP();
cakePHP2系と3系で使用している、$this->request->clientIp()では、ただ、LoadBarancerやリバースプロキシを使用している場合は内部での通信に利用されているプライベートIPが取得され、グローバルIPが取得できないようです。
その際は、下記のようにするとグローバルIPを取得できます。
$ip = $this->request->clientIp(false);
$this->request->clientIp()のIPの引数にfalseを与えることでグローバルIPアドレスが取得できます。
しかし、引数falseの時のみ HTTP_X_FORWARDED_FOR が参照されますが、falseをデフォルトにするとクライアント側でヘッダーを偽装するだけでIPを誤魔化せることになります。詳細を知りたい方は、clientIpのメソッド内を覗いてみてください。
なので、もし開発時に「本番環境でロードバランサー配下で使うかどうかわからないけどIPを取得する時は常にfalseにしとこう」と言ったことでclientIp()の引数を常にfalseにしてしまい、運用時にロードバランサーは使用しないということになると、セキュリティリスクが1個出来上がる可能性があります。
下記のリンクに実際に被害にあったケースが書かれています。
・CakePHPの$this->request->clientIP()の不正利用
PHPでのグローバルIPの取得
ちなみに、PHPでロードバランサーなどを使用している場合にグローバルIPを取得したい場合は、下記のようにやるそうです。
$_SERVER[‘HTTP_X_FORWARDED_FOR’]にロードバランサーなどを経由した際のIPアドレスがカンマ区切りで格納されており、一番最初のIPアドレスがクライアントのグローバルIPアドレスとなります。
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ipArray = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = $ipArray[0]; } else { $ip = $_SERVER['REMOTE_ADDR']; }
cakePHPでIPアドレスを取得する場合は、なるべくCakePHPのメソッドでやりたいですが、PHPで直接ロジックを切ってしまうのも手かもしれません。
[参考]
・PHP ロードバランサ経由のクライアントのIP取得ができない
・CakePHP Get IP Address