设置 $_SERVER['HTTP_CLIENT_IP'] 的值是否为空字符串?
我有一个简单的脚本来确定用户的 IP 地址:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
现在在网络上的某个地方我看到有人使用这个脚本:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
我想知道我的实现是否已损坏..我是否需要检查 $_SERVER[' 的值HTTP_CLIENT_IP']
、$_SERVER['HTTP_X_FORWARDED_FOR']
或 $_SERVER['REMOTE_ADDR']
为空?或者实际上没有必要这样做?
I have a simple script which determines the user's IP address:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
Now on the Net somewhere I saw someone using this script:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
I was wondering if my implementation is broken.. Do I need to check if the value of $_SERVER['HTTP_CLIENT_IP']
, $_SERVER['HTTP_X_FORWARDED_FOR']
, or $_SERVER['REMOTE_ADDR']
is empty? Or is it actually unnecessary to do so?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果你想找出客户端 IP 地址的原因真的很重要,那就把这些都搞砸吧。
这些标头值中的任何一个都可以被随意欺骗。
REMOTE_ADDR
是唯一真正可靠的信息,因为它是由处理请求的 Web 服务器传输给您的。理论上它也可以被伪造,但这比欺骗标头值和完全不同的类要困难得多的攻击。在反向代理背后的非常非常特定的托管环境中也有例外。在这些情况下,管理该代理的人员将能够知道您需要测试什么标头值。
If the reason why you want to find out the client's IP address is really important, screw all this stuff.
Any one of these header values can be freely spoofed.
REMOTE_ADDR
is the only really reliable information, as it is transmitted to you by your web server that is handling the request. It can be theoretically falsified as well, but that is much, much harder than spoofing a header value, and an entirely different class of attack.There are exceptions in very, very specific hosting environments behind reverse proxies. In those cases the person administering that proxy will be able to tell what header value you need to test for.
来自 Kohanas 的 Request 类:
这已经是最好的了。请注意
Request::$trusted_proxies
数组,在本例中,您的$ip
var 是Request::$client_ip
。From Kohanas' Request class:
This is pretty much as good as it gets. Please note the
Request::$trusted_proxies
array and that your$ip
var isRequest::$client_ip
in this case.除非您明确知道您的应用程序是在反向代理后面配置的,否则请勿检查客户端 IP 的任何
HTTP_*
标头。无条件信任这些标头的值将允许用户欺骗其 IP 地址。唯一包含可靠值的
$_SERVER
字段是REMOTE_ADDR
。Do not check any
HTTP_*
headers for the client IP unless you specifically know your application is configured behind a reverse proxy. Trusting the values of these headers unconditionally will allow users to spoof their IP address.The only
$_SERVER
field containing a reliable value isREMOTE_ADDR
.这两件事实际上是相同的。在您找到的脚本中,作者只是在检查数组中的元素是否非空之前检查数组中的元素是否已设置。
关于使用
empty()
函数而不是比较,请检查 http://php.ini。净/空。由于您处理的是由环境设置的变量,而不是用户输入的变量,因此您选择两个选项中的哪一个并不重要。所以你的脚本应该完全没问题The two things are practically identical.. In the script you found, the author is just doing a check if the element in the array is set before checking that it is non-empty.
In regards to using the
empty()
-function instead of the comparison, check http://php.net/empty. Since you are dealing with a variable that is set by the environment and not a user input it doesn't matter which of the two options you choose. So your script should be perfectly fine