headerIP php_PHP正确获取客户端IP地址

现状

目前主流的函数方法:

function getIp()

{

if ($_SERVER["HTTP_CLIENT_IP"] && strcasecmp($_SERVER["HTTP_CLIENT_IP"], "unknown")) {

$ip = $_SERVER["HTTP_CLIENT_IP"];

} else {

if ($_SERVER["HTTP_X_FORWARDED_FOR"] && strcasecmp($_SERVER["HTTP_X_FORWARDED_FOR"], "unknown")) {

$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];

} else {

if ($_SERVER["REMOTE_ADDR"] && strcasecmp($_SERVER["REMOTE_ADDR"], "unknown")) {

$ip = $_SERVER["REMOTE_ADDR"];

} else {

if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],

"unknown")

) {

$ip = $_SERVER['REMOTE_ADDR'];

} else {

$ip = "unknown";

}

}

}

}

return ($ip);

}

echo getIp();

测试

curl伪造IP请求:

$ch = curl_init('http://localhost/ip.php');

//通用设置

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//不直接输出

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);//跟踪重定向

//伪造请求头

$ip = mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255);

$header = [

'CLIENT-IP: ' . $ip,

'X-FORWARDED-FOR: ' . $ip,

'X-REAL-IP: ' . $ip,

'Accept-Language: zh-CN,zh;',

];

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

$html = curl_exec($ch);

curl_close($ch);

echo $html;

输出SERVER数组,发现【HTTP_CLIENT_IP】、【HTTP_X_FORWARDED_FOR】、【HTTP_X_REAL_IP】是随机变动的IP地址。

主流方法根本不安全!

分析

为什么?

HTTP_CLIENT_IP:存在于http请求的header

HTTP_X_FORWARDED_FOR:请求转发路径,客户端IP,代理1IP,代理2IP......

HTTP_X_REAL_IP:这个用得比较少,暂不讨论。

这三个值都是从HTTP请求头获取的,所以并不可靠!

REMOTE_ADDR:是直接从TCP中获取的IP,基本不会被伪造!

返回查看$_SERVER数组,发现【REMOTE_ADDR】显示正确的IP!

所以直接用 $_SERVER['REMOTE_ADDR'] 就解决问题了?

其实还不行,如果客户端和服务器之间存在代理服务器,【REMOTE_ADDR】的值是最后一个代理服务器的IP!

只有第一台接收客户端请求的代理服务器的【REMOTE_ADDR】值才是客户的真实IP地址,要把该值传递下去!

解决方案

1. 客户端和服务器直连

function get_client_ip()

{

$ip = $_SERVER['REMOTE_ADDR'];

return $ip;

}

2. 客户端和服务器存在中间代理

第一层nginx代理设置:

proxy_set_header X-Forwarded-For $remote_addr;

其他层nginx代理设置:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

PHP代码:

function get_client_ip()

{

$ip = null;

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

$ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

$ip = trim(current($ip));

}

return $ip;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值