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 相关文章推荐
用php实现的下载css文件中的图片的代码
Feb 08 PHP
php开发过程中关于继承的使用方法分享
Jun 17 PHP
PHP CURL获取cookies模拟登录的方法
Nov 04 PHP
php 判断服务器操作系统的类型
Feb 17 PHP
ThinkPHP之A方法实例讲解
Jun 20 PHP
php实现删除空目录的方法
Mar 16 PHP
php基于CodeIgniter实现图片上传、剪切功能
May 14 PHP
PHP实现随机生成水印图片功能
Mar 22 PHP
ThinkPHP 模板引擎使用详解
May 07 PHP
php面向对象的用户登录身份验证
Jun 08 PHP
php过滤htmlspecialchars() 函数实现把预定义的字符转换为 HTML 实体用法分析
Jun 25 PHP
如何在Laravel5.8中正确地应用Repository设计模式
Nov 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
无法载入 mcrypt 扩展,请检查 PHP 配置终极解决方案
2011/07/18 PHP
如何在php中正确的使用json
2013/08/06 PHP
彻底删除thinkphp3.1案例blog标签的方法
2014/12/05 PHP
WAMP环境中扩展oracle函数库(oci)
2015/06/26 PHP
ThinkPHP中session函数详解
2016/09/14 PHP
PHP实现文件上传下载实例
2016/10/18 PHP
php事务回滚简单实现方法示例
2017/03/28 PHP
PHP调用Mailgun发送邮件的方法
2017/05/04 PHP
js window.print实现打印特定控件或内容
2013/09/16 Javascript
关于删除时的提示处理(确定删除吗)
2013/11/03 Javascript
javascript轻量级模板引擎juicer使用指南
2014/06/22 Javascript
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
2016/01/19 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
BootStrap和jQuery相结合实现可编辑表格
2016/04/21 Javascript
jQuery插件WebUploader实现文件上传
2016/11/07 Javascript
详解获取jq ul第一个li定位的四种解决方案
2016/11/23 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
微信小程序实现星级评分和展示
2018/07/05 Javascript
使用微信小程序开发弹出框应用实例详解
2018/10/18 Javascript
jQuery zTree插件快速实现目录树
2019/08/16 jQuery
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
vue路由拦截器和请求拦截器知识点总结
2019/11/08 Javascript
[02:53]2018年度DOTA2最佳战队-完美盛典
2018/12/17 DOTA
Python的Scrapy爬虫框架简单学习笔记
2016/01/20 Python
Python基于递归算法求最小公倍数和最大公约数示例
2018/07/27 Python
Python使用lambda抛出异常实现方法解析
2020/08/20 Python
python 装饰器的使用示例
2020/10/10 Python
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
网络宣传方案
2014/03/15 职场文书
领导班子自我剖析材料
2014/08/16 职场文书
房产协议书范本2014
2014/09/30 职场文书
学校端午节活动总结
2015/02/11 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
聘任书格式及范文
2015/09/21 职场文书
python 实现的截屏工具
2021/05/08 Python