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

时间:2021-10-10 06:40:54

In other words, how can I tell if the person using my web application is on the server it resides on? If I remember correctly, PHPMyAdmin does something like this for security reasons.

换句话说,如何判断使用web应用程序的人是否位于其所在的服务器上?如果我没记错的话,PHPMyAdmin出于安全原因做了类似的事情。

8 个解决方案

#1


124  

You can also use $_SERVER['REMOTE_ADDR'] for which IP address of the client requesting is given by the web server.

您还可以使用$_SERVER['REMOTE_ADDR'], web服务器给出请求的客户端的IP地址。

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

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

#2


15  

As a complement, as a function...

作为补充,作为函数……

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

#3


14  

$_SERVER["REMOTE_ADDR"] should tell you the user's IP. It's spoofable, though.

$_SERVER["REMOTE_ADDR"]应该告诉您用户的IP。不过,这是spoofable。

Check this bounty question for a very detailed discussion.

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

I think what you remember with PHPMyAdmin is something different: Many MySQL Servers are configured so that they can only be accessed from localhost for security reasons.

我认为PHPMyAdmin所记得的东西是不同的:许多MySQL服务器都配置好了,只有出于安全原因,才可以从本地主机访问它们。

#4


13  

Newer OS users (Win 7, 8) may also find it necessary to include an IPV6-format remote address in their whitelist array:

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

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

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

#5


6  

It doesn't seem you should use $_SERVER['HTTP_HOST'], because this is the value in http header, easily faked.

看起来不应该使用$_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.

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

#6


0  

If you want to have a whitelist / allowlist that supports static IPs and dynamic names.

如果您想要一个支持静态IPs和动态名称的whitelist / allowlist。

For example:

例如:

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

This way you could set a list of names/IPs that will be able (for sure) to be detected. Dynamic names add more flexibility for accessing from different points.

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

You have two common options here, you could set a name in your local hosts file or you could just use one dynamic name provider that could be found anywhere.

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

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

这个函数缓存结果,因为gethostbyname是一个非常慢的函数。

For this pupose I've implemented this 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;
}

For better reliability you could replace the $_SERVER['REMOTE_ADDR'] for the get_ip_address() that @Pekka mentioned in his post as "this bounty question"

为了更好的可靠性,您可以将$_SERVER['REMOTE_ADDR']替换为get_ip_address(), @Pekka在他的文章中提到这个问题为“赏金问题”

#7


0  

How about to compare $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'] to determine if client is on the same machine as server?

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

#8


-1  

I found a easy answer.

我找到一个简单的答案。

Because all local drives have C: or D: or F: ... etc.

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

Just detect if the second character is a :

只要检测第二个字符是否是a:

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

#1


124  

You can also use $_SERVER['REMOTE_ADDR'] for which IP address of the client requesting is given by the web server.

您还可以使用$_SERVER['REMOTE_ADDR'], web服务器给出请求的客户端的IP地址。

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

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

#2


15  

As a complement, as a function...

作为补充,作为函数……

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

#3


14  

$_SERVER["REMOTE_ADDR"] should tell you the user's IP. It's spoofable, though.

$_SERVER["REMOTE_ADDR"]应该告诉您用户的IP。不过,这是spoofable。

Check this bounty question for a very detailed discussion.

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

I think what you remember with PHPMyAdmin is something different: Many MySQL Servers are configured so that they can only be accessed from localhost for security reasons.

我认为PHPMyAdmin所记得的东西是不同的:许多MySQL服务器都配置好了,只有出于安全原因,才可以从本地主机访问它们。

#4


13  

Newer OS users (Win 7, 8) may also find it necessary to include an IPV6-format remote address in their whitelist array:

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

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

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

#5


6  

It doesn't seem you should use $_SERVER['HTTP_HOST'], because this is the value in http header, easily faked.

看起来不应该使用$_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.

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

#6


0  

If you want to have a whitelist / allowlist that supports static IPs and dynamic names.

如果您想要一个支持静态IPs和动态名称的whitelist / allowlist。

For example:

例如:

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

This way you could set a list of names/IPs that will be able (for sure) to be detected. Dynamic names add more flexibility for accessing from different points.

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

You have two common options here, you could set a name in your local hosts file or you could just use one dynamic name provider that could be found anywhere.

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

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

这个函数缓存结果,因为gethostbyname是一个非常慢的函数。

For this pupose I've implemented this 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;
}

For better reliability you could replace the $_SERVER['REMOTE_ADDR'] for the get_ip_address() that @Pekka mentioned in his post as "this bounty question"

为了更好的可靠性,您可以将$_SERVER['REMOTE_ADDR']替换为get_ip_address(), @Pekka在他的文章中提到这个问题为“赏金问题”

#7


0  

How about to compare $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'] to determine if client is on the same machine as server?

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

#8


-1  

I found a easy answer.

我找到一个简单的答案。

Because all local drives have C: or D: or F: ... etc.

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

Just detect if the second character is a :

只要检测第二个字符是否是a:

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