php获取客户端IP

比较 HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR REMOTE_ADDR

最近做项目的时候,遇到一个需要记录客户端ip的,后台语言是php,我想了一下,用REMOTE_ADDR吧。可是呢,后来发现其实这个还有很多其他的获取方式,HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR都可以获取,我仔细查了一下资料,总结一下这三者的区别,另附完整解决方法:

  1. HTTP_CLIENT_IP头是有的,只是未成标准,不一定服务器都实现了。
  2. HTTP_X_FORWARDED_FOR 是有标准定义,用来识别经过HTTP代理后的客户端IP地址,格式:clientip,proxy1,proxy2。详细解释见 http://zh.wikipedia.org/wiki/X-Forwarded-For
  3. REMOTE_ADDR 是可靠的, 它是最后一个跟你的服务器握手的IP,可能是用户的代理服务器,也可能是自己的反向代理。

顺便说下$_SERVER和getenv的区别,getenv不支持IIS的isapi方式运行的php

function getIp() {
    if (getenv ( "HTTP_CLIENT_IP" ) && strcasecmp ( getenv ( "HTTP_CLIENT_IP" ), "unknown" )) {
        $ip = getenv ( "HTTP_CLIENT_IP" );
    } elseif (getenv ( "HTTP_X_FORWARDED_FOR" ) && strcasecmp ( getenv ( "HTTP_X_FORWARDED_FOR" ), "unknown" )) {
        $ip = getenv ( "HTTP_X_FORWARDED_FOR" );
    } elseif (getenv ( "REMOTE_ADDR" ) && strcasecmp ( getenv ( "REMOTE_ADDR" ), "unknown" )) {
        $ip = getenv ( "REMOTE_ADDR" );
    } elseif (isset ( $_SERVER ['REMOTE_ADDR'] ) && $_SERVER ['REMOTE_ADDR'] && strcasecmp ( $_SERVER ['REMOTE_ADDR'], "unknown" )) {
        $ip = $_SERVER ['REMOTE_ADDR'];
    } else {
        $ip = "unknown";
    }
    return ($ip);
}

REMOTE_ADDR不可以显式的伪造,虽然可以通过代理将ip地址隐藏,但是这个地址仍然具有参考价值,因为它就是与你的服务器实际连接的ip地址。

相比之下,前两种ip地址都可以通过http header来伪造,但并不意味着它们一无是处。生产环境中很多服务器隐藏在负载均衡节点后面,你通过REMOTE_ADDR只能获取到负载均衡节点的ip地址,一般的负载均衡节点会把前端实际的ip地址通过HTTP_CLIENT_IP或者HTTP_X_FORWARDED_FOR这两种http头传递过来

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容