如何检测用户是否在 PHP 本地主机上?

换句话说,我怎样才能知道使用我的 Web 应用程序的人是否在它所在的服务器上?如果我没有记错的话,出于安全原因,PHPMyAdmin 会执行类似的操作。

104789 次浏览

$_SERVER["REMOTE_ADDR"]应该能告诉你用户的 IP 地址,不过它是可欺骗的。

检查 这个赏金问题以获得非常详细的讨论。

我想您记得 PHPMyAdmin 有些不同: 许多 MySQL 服务器都配置为只能从本地主机访问,这是出于安全原因。

您还可以使用 $_SERVER['REMOTE_ADDR'],Web 服务器为其提供客户端请求的 IP 地址。

$whitelist = array(
'127.0.0.1',
'::1'
);


if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
// not valid
}

似乎不应该使用 $_SERVER['HTTP_HOST'],因为这是 http 头中的值,很容易伪造。

You may use $_SERVER["REMOTE_ADDR"] too, this is the more secure value, but it is also possible to fake. This remote_addr is the address where Apache returns result to.

较新的操作系统用户(Win 7,8)可能也会发现有必要在他们的白名单数组中包含一个 IPV6格式的远程地址:

$whitelist = array('127.0.0.1', "::1");


if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
// not valid
}

作为补充,作为功能..。

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}

如果你想有一个支持 静态 IP 地址有活力的名字白名单/允许名单

For example:

$whitelist = array("localhost", "127.0.0.1", "devel-pc.ds.com", "liveserver.com");
if (!isIPWhitelisted($whitelist)) die();

通过这种方式,您可以设置一个 名称/IP 地址列表,这个列表将能够(肯定地)被检测到。动态名称增加了从不同点访问的灵活性。

这里有两个常见的选项,可以在 本地主机文件中设置一个名称,也可以只使用一个可以在任何地方找到的 动态名称提供程序

This function CACHES results because gethostbyname is a very slow function.

为了这个目的,我实现了这个函数:

function isIPWhitelisted($whitelist = false)
{
if ( isset($_SESSION) && isset($_SESSION['isipallowed']) )
{ return $_SESSION['isipallowed'];  }


// This is the whitelist
$ipchecklist = array("localhost", "127.0.0.1", "::1");
if ($whitelist) $ipchecklist = $whitelist;


$iplist = false;
$isipallowed = false;


$filename = "resolved-ip-list.txt";
$filename = substr(md5($filename), 0, 8)."_".$filename; // Just a spoon of security or just remove this line


if (file_exists($filename))
{
// If cache file has less than 1 day old use it
if (time() - filemtime($filename) <= 60*60*24*1)
$iplist = explode(";", file_get_contents($filename)); // Read cached resolved ips
}


// If file was not loaded or found -> generate ip list
if (!$iplist)
{
$iplist = array(); $c=0;
foreach ( $ipchecklist as $k => $iptoresolve )
{
// gethostbyname: It's a VERY SLOW function. We really need to cache the resolved ip list
$ip = gethostbyname($iptoresolve);
if ($ip != "") $iplist[$c] = $ip;
$c++;
}


file_put_contents($filename, implode(";", $iplist));
}


if (in_array($_SERVER['REMOTE_ADDR'], $iplist)) // Check if the client ip is allowed
$isipallowed = true;


if (isset($_SESSION)) $_SESSION['isipallowed'] = $isipallowed;


return $isipallowed;
}

为了更好的可靠性,你可以替换 Get _ ip _ address ()$_ SERVER [‘ REMOTE _ ADDR’],这是@Pekka 在他的 post中提到的 “这个赏金问题”

I found a easy answer.

因为所有本地驱动器都有 C: 或 D: 或 F: ... 等等。

只需检测第二个字符是否为:

if ( substr_compare(getcwd(),":",1,1) == 0)
{
echo '<script type="text/javascript">alert(" The working dir is at the local computer ")</script>';
$client_or_server = 'client';
}
else
{
echo '<script type="text/javascript">alert(" The working dir is at the server ")</script>';
$client_or_server = 'server';
}

如何比较 $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']来确定客户端是否与服务器在同一台机器上?

我很抱歉,但这些答案对我来说都很糟糕。我建议重新措辞这个问题,因为在某种意义上,所有机器都是“本地主机”。

问题应该是: 根据在哪台机器上执行代码,如何运行不同的代码路径。

在我看来,最简单的方法是创建一个名为 devMACHINE 的文件或者任何你真正想要的,然后简单地检查

File _ vis (‘ DevMACHINE’)

记住在上传到实时主机环境时排除此文件!

这个解决方案不依赖于网络配置,它不能被欺骗,并且很容易在运行“ live-code”和“ dev-code”之间切换。

Used this simple PHP condition

if($_SERVER['HTTP_HOST'] == 'localhost')
{
die('Localhost');
}

Also there is another easy way to check is localhost or not: 这段代码检查 ip 是在私有范围还是保留范围,如果是,那么我们是在本地主机

  • 支援 ipv4及 ipv6。
  • 支持 ip 范围,如127.0.0.1-127.255.255.255

PHP Code:

function is_localhost() {


$server_ip = null;


if ( defined( 'INPUT_SERVER' ) && filter_has_var( INPUT_SERVER, 'REMOTE_ADDR' ) ) {
$server_ip = filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
} elseif ( defined( 'INPUT_ENV' ) && filter_has_var( INPUT_ENV, 'REMOTE_ADDR' ) ) {
$server_ip = filter_input( INPUT_ENV, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
$server_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP );
}


if ( empty( $server_ip ) ) {
$server_ip = '127.0.0.1';
}


return empty( filter_var( $server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE ));
}
  1. for get ip i use filter_input to avoid ip injection in code by user.
  2. 在某些情况下,在 CGI 脚本中不支持 filter_input,所以如果不存在,我用 $_SERVER变量以正常方式获得 ip。
  3. FILTER_VALIDATE_IPFILTER_FLAG_NO_PRIV_RANGE都在 php 网站上有记载,你可以在 这个链接中找到更多的信息。