如何检测用户是否在PHP的localhost上?


Answers:


177

您还可以使用$_SERVER['REMOTE_ADDR']Web服务器指定客户端请求的IP地址。

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

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

2
实际上,这比欺骗IP更容易破解。您应该真正更改它。
Pekka 2010年

3
@ skcin7可能是您的服务器设置。核实。
毛里求斯2012年

4
@Pekka웃您可以只发送eg Host: 127.0.0.1,它将被填充到中HTTP_HOST,所以这根本不是可靠的方法。
DejanMarjanović2013年

4
是的,这是不正确的建议,目前仍是这样,需要对其进行编辑或下推。
Pekka

3
不要忘记IPv6:$whitelist = array('127.0.0.1', '::1');
CrazyMax 2014年

26

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

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

5
作为一种好的做法,我建议添加“ else return false;”。因此该函数始终返回布尔值。或者,只需完全删除“ if”,然后改为“返回in_array($ _SERVER ['REMOTE_ADDR'],$ whitelist);”
Joe Irby

15

较新的OS用户(Win 7、8)也可能发现有必要在其白名单数组中包括IPV6格式的远程地址:

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

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

14

$_SERVER["REMOTE_ADDR"]应该告诉您用户的IP。但是,这是可欺骗的。

检查这个赏金问题进行非常详细的讨论。

我认为您对PHPMyAdmin的了解与众不同:配置了许多MySQL服务器,以便出于安全原因只能从本地主机访问它们。


值得注意的是,某些MySQL服务器是通过不绑定到公共接口来配置的。同样,如果您想以同样的方式限制PHP应用程序,则应考虑通过仅绑定到内部接口的apache实例来提供服务。
Frank Farmer 2010年

8

抱歉,所有这些答案对我来说似乎都很糟糕。我建议改写这个问题,因为从某种意义上说,所有机器都是“ localhost”。

问题应该是;如何运行不同的代码路径,具体取决于在哪台计算机上执行。

我认为,最简单的方法是创建一个名为DEVMACHINE的文件或您真正想要的任何东西,然后简单地检查

file_exists('DEVMACHINE')

上载到实时托管环境时,请记住要排除此文件!

该解决方案不依赖于网络配置,它不能被欺骗,可以轻松地在运行的“实时代码”和“开发代码”之间进行切换。


6

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

您也可以使用$_SERVER["REMOTE_ADDR"],这是更安全的值,但也可能伪造。这remote_addr是Apache返回结果的地址。


REMOTE_ADDR可以伪造,但是如果您想将其伪造为127.0.0.1::1,则需要对机器进行折衷,而对于这种机器,欺骗REMOTE_ADDR最少的是您。相关答案-stackoverflow.com/a/5092951/3774582
Goose Goose

1

如果要拥有一个支持静态IP动态名称白名单/允许列表

例如:

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

这样,您可以设置一个名称/ IP列表,这些列表将能够(肯定)被检测到。动态名称为从不同点访问提供了更大的灵活性。

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

由于gethostbyname是一个非常慢的函数,因此会导致此函数缓存。

为此,我实现了以下功能:

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;
}

为了更好的可靠性,你可以替换$ _ SERVER [“REMOTE_ADDR”]get_ip_address()是@Pekka在他提到的职位“这个赏金问题”


1
我不知道为什么有人为我的答案设置了否定的分数,而显然却提供了动态的名称解析,而其他人则没有。DNS解析速度很慢,这就是为什么需要缓存解析度的原因。
Heroselohim

1

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


$_SERVER['SERVER_ADDR']并不总是可靠地返回服务器地址,例如,如果使用负载均衡器,它将返回我认为的负载均衡器的IP地址。
迈克W

-2

我找到了一个简单的答案。

因为所有本地驱动器都有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';
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.