PHP获取客户端真实IP地址的5种情况分析和实现代码


Posted in PHP onJuly 08, 2014

在PHP获取客户端IP中常使用 $_SERVER["REMOTE_ADDR"] 。
(1) 但如果客户端是使用代理服务器来访问,那取到的是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。
(2) 但只有客户端使用“透明代理”的情况下,$_SERVER["HTTP_X_FORWARDED_FOR"] 的值才是客户端真正的IP(如果是多层代理,该值可能是由客户端真正IP和多个代理服务器的IP组成,由逗号“,”分隔)。
(3) 而在“匿名代理”、“欺骗性代理”的情况下是代理服务器的IP值(如果是多层代理,该值可能由多个代理服务器的IP组成,由逗号“,”分隔)。
(4) 在“高匿名代理”的情况下是空值。

关于HTTP头信息中的REMOTE_ADDR、HTTP_FORWARDED_FOR值,分析如下,假设客户端真实IP是221.5.252.160:

 一、没有使用代理服务器的PHP获取客户端IP情况:

REMOTE_ADDR = 221.5.252.160

HTTP_VIA=没数值或者不显示

HTTP_X_FORWARDED_FOR = 没数值或不显示

二、使用透明代理服务器的情况:Transparent Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

HTTP_VIA=代理服务器IP

HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)

 这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的。

三、使用普通匿名代理服务器的PHP获取客户端IP情况:Anonymous Proxies

REMOTE_ADDR = 最后一个代理服务器 IP

HTTP_VIA=代理服务器IP

HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)

 这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的。

四、使用欺骗性代理服务器的情况:Distorting Proxies

REMOTE_ADDR = 代理服务器 IP

HTTP_VIA=代理服务器IP

 HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215)

这种情况下同样透露了客户端是使用了代理服务器,但编造了一个虚假的随机IP(220.4.251.159)代替客户端的真实IP来欺骗它。

五、使用高匿名代理服务器的PHP获取客户端IP情况:High Anonymity Proxies (Elite proxies)

REMOTE_ADDR = 代理服务器 IP
HTTP_VIA=没数值或者不显示

 HTTP_X_FORWARDED_FOR = 没数值或不显示。

无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP 头消息。因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值。

PHP获取客户端IP时另外一点需注意,使用函数getenv('HTTP_X_FORWARDED_FOR')或getenv('REMOTE_ADDR') 也可以如上代码一样取得同样的效果。但getenv()不支持在IIS的isapi方式下运行的PHP。

REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。

HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。

$_SERVER['REMOTE_ADDR']; //访问端(有可能是用户,有可能是代理的)IP

$_SERVER['HTTP_CLIENT_IP'];  //代理端的(有可能存在,可伪造)

$_SERVER['HTTP_X_FORWARDED_FOR']; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)

根据以上几种情况写出的PHP代码:

<?php

function getip() {  

 $unknown = ‘unknown';  

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

  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];  

 } 

 elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {  

  $ip = $_SERVER['REMOTE_ADDR'];  

 } 

}

?>
PHP 相关文章推荐
PHP6 先修班 JSON实例代码
Aug 23 PHP
php数据库连接时容易出错的特殊符号问题
Sep 01 PHP
PHP下常用正则表达式整理
Oct 26 PHP
php读取excel文件的简单实例
Aug 26 PHP
PHP防止表单重复提交的几种常用方法汇总
Aug 19 PHP
PHP中file_get_contents高?用法实例
Sep 24 PHP
简单实用的PHP防注入类实例
Dec 05 PHP
laravel容器延迟加载以及auth扩展详解
Mar 02 PHP
注意!PHP 7中不要做的10件事
Sep 18 PHP
jquery不支持toggle()高(新)版本的问题解决
Sep 24 PHP
PHP memcache在微信公众平台的应用方法示例
Sep 13 PHP
php给数组赋值的实例方法
Sep 26 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
Jul 08 #PHP
PHP生成短网址的3种方法代码实例
Jul 08 #PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 #PHP
php中函数前加&amp;符号的作用分解
Jul 08 #PHP
PHP实现的连贯操作、链式操作实例
Jul 08 #PHP
PHP类中的魔术方法(Magic Method)简明总结
Jul 08 #PHP
PHP的魔术常量__METHOD__简介
Jul 08 #PHP
You might like
DC游戏Steam周三特惠 《蝙蝠侠》阿卡姆系列平史低
2020/04/09 欧美动漫
两种php调用Java对象的方法
2006/10/09 PHP
由php的call_user_func传reference引发的思考
2010/07/23 PHP
php使用curl并发减少后端访问时间的方法分析
2016/05/12 PHP
thinkPHP的表达式查询用法详解
2016/09/14 PHP
Laravel中任务调度console使用方法小结
2017/05/07 PHP
php中错误处理操作实例分析
2019/08/23 PHP
编写跨浏览器的javascript代码必备[js多浏览器兼容写法]
2008/10/29 Javascript
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
jquery form 加载数据示例
2014/04/21 Javascript
jQuery Ajax使用实例
2015/04/16 Javascript
javascript实现的右下角弹窗实例
2015/04/24 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
2015/12/13 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
javascript ASCII和Hex互转的实现方法
2016/12/27 Javascript
Vue2学习笔记之请求数据交互vue-resource
2017/02/23 Javascript
webpack独立打包和缓存处理详解
2017/04/03 Javascript
JS简单判断是否在微信浏览器打开的方法示例
2019/01/08 Javascript
Vue 设置axios请求格式为form-data的操作步骤
2019/10/29 Javascript
微信小程序如何实现radio单选框单击打勾和取消
2020/01/21 Javascript
VSCode Vue开发推荐插件和VSCode快捷键(小结)
2020/08/08 Javascript
Vue中使用wangeditor富文本编辑的问题
2021/02/07 Vue.js
python清除指定目录内所有文件中script的方法
2015/06/30 Python
Python编程求质数实例代码
2018/01/31 Python
基于Django与ajax之间的json传输方法
2018/05/29 Python
文秘专业毕业生就业推荐信
2013/11/08 职场文书
个人主要事迹材料
2014/08/26 职场文书
党政领导班子四风问题对照检查材料思想汇报
2014/10/02 职场文书
升学宴学生答谢词
2015/01/05 职场文书
小学教师党员承诺书
2015/04/27 职场文书
学校捐书倡议书
2015/04/27 职场文书
员工福利申请报告
2015/05/15 职场文书
立春观后感
2015/06/18 职场文书
springcloud之Feign超时问题的解决
2021/06/24 Java/Android