如何在 PHP 中获取客户端 IP 地址

分享于2022年07月17日 environment-variables ip-address php 问答
【问题标题】:如何在 PHP 中获取客户端 IP 地址(How to get the client IP address in PHP)
【发布时间】:2022-06-29 09:59:26
【问题描述】:

如何使用 PHP 获取客户端 IP 地址?

我想记录通过他/她的 IP 地址登录我网站的用户。

  • 请参阅 RFC6302 以了解有关记录内容的建议,特别是现在要记住记录端口而不仅仅是地址。
  • 对于那些跟踪用户的提醒,在全球的几个地区,ISPS 正在使用 CGNAT,这使得信任单纯的 IP 地址变得更加复杂
  • function getUserIpAddr(){ if(!empty($_SERVER['HTTP_CLIENT_IP'])){ $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }else{ $ip = $_SERVER['REMOTE_ADDR']; } 返回 $ip; }
  • 你应该使用 Abstract IP detection 。价值在于它会让您知道 IP 是否位于代理或 VPN 后面,我认为这很重要。他们有一个 PHP sn-p,您可以从中复制您的请求。

【解决方案1】:

无论您做什么,请确保不要信任从客户端发送的数据。 $_SERVER['REMOTE_ADDR'] 包含连接方的真实 IP 地址。这是您能找到的最可靠的值。

但是,它们可能位于代理服务器之后,在这种情况下,代理可能设置了 $_SERVER['HTTP_X_FORWARDED_FOR'] ,但该值很容易被欺骗。例如,它可以由没有代理的人设置,或者 IP 可以是来自代理后面的 LAN 的内部 IP。

这意味着如果您要保存 $_SERVER['HTTP_X_FORWARDED_FOR'] ,请确保 保存 $_SERVER['REMOTE_ADDR'] 值。例如。通过将这两个值保存在数据库的不同字段中。

如果您要将 IP 作为字符串保存到数据库中,请确保您有至少 45 个字符 的空间。 IPv6 将继续存在,这些地址比旧的 IPv4 地址大。

(请注意,IPv6 通常最多使用 39 个字符,但也有一个特殊的 IPv6 notation for IPv4 addresses ,其完整形式最多可包含 45 个字符。因此,如果您知道自己在做什么,则可以使用 39 个字符,但如果您只想设置并忘记它,使用 45)。

  • 不错的答案!我已经在为我的服务器使用 $_SERVER['REMOTE_ADDR'],我喜欢你包含另一种方式,以及优点和缺点。
  • 注意: REMOTE_ADDR 可能 包含 TCP 连接的真实 IP。这完全取决于您的 SAPI。确保您的 SAPI 配置正确,以便 $_SERVER['REMOTE_ADDR'] 实际上返回 TCP 连接的 IP。失败可能会导致一些严重的漏洞,例如,StackExchange 曾经通过检查 REMOTE_ADDR 来授予 admin 访问权限 ,以查看它是否匹配“localhost”,不幸的是SAPI 的配置...... ..................................................... ....................
  • ................................................ ................................有一个漏洞(它需要 HTTP_X_FORWARDED_FOR 作为输入),它允许非管理员通过更改 HTTP_X_FORWARDED_FOR 标头获得管理员访问权限。另见 blog.ircmaxell.com/2012/11/anatomy-of-attack-how-i-hacked.html
  • @EmilVikström 我尝试回显所有内容 - $_SERVER["HTTP_CLIENT_IP"]; $_SERVER['REMOTE_ADDR']; $_SERVER['HTTP_X_FORWARDED_FOR']; $_SERVER['HTTP_X_FORWARDED']; $_SERVER['HTTP_FORWARDED_FOR']; $_SERVER['HTTP_FORWARDED'];和 $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; - 唯一一个从两者都返回一些 IP 值 - 通过我的浏览器和代理服务器直接访问是 REMOTE_ADDR var。其余所有 6 个变量都以空白形式出现。这里错过了什么? .....
  • .....@Pacerier - 你身边的任何 cmets 以及上面