目前我得到usr的IP是这样的:
if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) ){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif ( isset($_SERVER['REMOTE_ADDR']) ) {
$ip = $_SERVER['REMOTE_ADDR'];
}
// IPs
+----+----------------+-------------+
| id | user_ip | date_time |
+----+----------------+-------------+
| 1 | 43.12.9.9 | 1468070172 |
| 2 | 173.3.0.1 | 1468070667 |
+----+----------------+-------------+
但是现在,我在这里读到了这一点:
如果要保存
$_SERVER['HTTP_X_FORWARDED_FOR']
,请确保同时保存$_SERVER['REMOTE_ADDR']
值。 例如,通过将两个值保存在数据库的不同字段中。
所以我将我的代码更改为:
$remote_add = $_SERVER['REMOTE_ADDR']; // I don't use isset() for this becase it is always set
$http_x_forwarded_for = isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : null;
// IPs
+----+----------------+----------------+-------------+
| id | remote | forwarded | date_time |
+----+----------------+----------------+-------------+
| 1 | 43.12.9.9 | NULL | 1468070172 |
| 2 | 93.35.40.1 | 173.3.0.1 | 1468070667 |
+----+----------------+----------------+-------------+
好的,我正在做的是正确的吗?我问这个是因为一些专业程序员告诉我你做什么是无用的,你只需要列作为用户的IP。 好吧,请有人清理我吗?如何正确获取用户的 IP?
我的最终代码:
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key){
if (array_key_exists($key, $_SERVER) === true){
foreach (explode(',', $_SERVER[$key]) as $header){
$header = trim($header); // just to be safe
if (filter_var($header, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
$header = $header;
}
}
}
}
$user_ip = $_SERVER['REMOTE_ADDR'];
// IPs
+----+----------------+----------------+-------------+
| id | user_ip | header | date_time |
+----+----------------+----------------+-------------+
| 1 | 43.12.9.9 | NULL | 1468070172 |
| 2 | 93.35.40.1 | 173.3.0.1 | 1468070667 |
+----+----------------+----------------+-------------+
在 http-request 中,有人可以欺骗除远程地址之外的任何信息。如果没有实际访问该 IP 地址上的调制解调器或该调制解调器/路由器后面的计算机,则无法完成 tcp 握手。REMOTE_ADDR
密钥始终设置为连接到服务器的设备。在某些情况下,该设备是用户使用的代理。
HTTP_X_FORWARDED_FOR
标头是一个标头,不错的代理使用它来表示原始 IP 地址是什么,该地址命令代理代表他们加载页面。但是,此标头可能是欺骗性的。有人可以发送此标头中的任何信息,包括有趣的内容,例如127.0.0.1
(localhost),甚至是仅假定该字段只能包含数字和点的服务器的html或脚本,甚至是不使用准备好的查询插入这些内容的服务器的原始sql语句。
唯一保证正确的信息是远程 IP,但不一定是用户的 IP。如果远程 IP 是代理,则记录远程 IP 可能允许您联系欺诈行为的远程代理的所有者,让他们搜索实际发出该请求的 IP 的日志。在某些情况下,转发的 IP 可以在代理不打算掩盖使用代理的人的身份的情况下保护您的时间,这将允许您对该 IP 而不是代理本身采取一些措施。
有时使用 HTTP_X_FORWARDED_FOR
标头,有时使用 REMOTE_ADDR
进行有根据的猜测将导致数据不可用。您无法知道哪些数据可以信任,哪些数据可以信任。
我问这个是因为一些专业程序员告诉我你做什么是无用的,你只需要列作为用户的IP。
如果你正在做的事情是无用的,完全取决于你使用它的目的。如果要显示转发的字段,请记住正确转义显示该字段的上下文的所有特殊字符。如果您只存储一个 ip,它将是远程 ip,完全忽略HTTP_X_FORWARDED_FOR
标头。这是您唯一可以完全信任的信息。