Как я могу определить, находится ли пользователь на локальном хосте в PHP?

Другими словами, как узнать, находится ли человек, использующий мое веб-приложение, на сервере, на котором оно находится? Если я правильно помню, PHPMyAdmin делает что-то подобное из соображений безопасности.


person Richie Marquez    schedule 12.01.2010    source источник


Ответы (10)


Вы также можете использовать $_SERVER['REMOTE_ADDR'], для которого IP-адрес запрашивающего клиента предоставляется веб-сервером.

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

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}
person mauris    schedule 12.01.2010
comment
Что сделало бы это на самом деле легче сломать, чем спуфинг IP. Вы действительно должны изменить его. - person Pekka; 13.01.2010
comment
Это не работает для меня. $_SERVER['HTTP_HOST'] возвращает текстовую часть моего домена (например, если домен был www.example.com). - person skcin7; 18.01.2012
comment
@skcin7 может быть настройкой вашего сервера. Проверь это. - person mauris; 18.01.2012
comment
@Pekka웃 вы можете просто отправить, например. Host: 127.0.0.1, и он будет заполнен в HTTP_HOST, так что это вообще ненадежный метод. - person Dejan Marjanović; 19.03.2013
comment
Да, это плохой совет, и в его нынешнем виде его нужно отредактировать или проголосовать за него. - person Pekka; 03.08.2013
comment
Отредактировал пост только что. Вы, ребята, можете напрямую редактировать этот ответ, не дожидаясь меня. - person mauris; 04.08.2013
comment
Не забудьте IPv6 : $whitelist = array('127.0.0.1', '::1'); - person CrazyMax; 19.02.2014
comment
@crazy добавил адрес IPv6! - person mauris; 21.02.2014
comment
Не лучше ли использовать filter_input(INPUT_SERVER, 'REMOTE_ADDR') вместо $_SERVER['REMOTE_ADDR']. - person ban-geoengineering; 26.04.2017

Как дополнение, как функция...

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
    return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}
person Jens Törnell    schedule 11.02.2014
comment
В качестве хорошей практики я бы рекомендовал добавить else return false; чтобы функция всегда возвращала логическое значение. Или, наоборот, просто полностью удалите if и вместо этого верните in_array($_SERVER['REMOTE_ADDR'], $whitelist); - person Joe Irby; 01.02.2018

Пользователи более новых ОС (Win 7, 8) также могут счесть необходимым включить удаленный адрес в формате IPV6 в свой массив белого списка:

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

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

$_SERVER["REMOTE_ADDR"] должен сообщить вам IP-адрес пользователя. Однако это подделка.

Проверьте < strong>этот вопрос о щедрости для очень подробного обсуждения.

Я думаю, что вы помните с PHPMyAdmin, это нечто другое: многие серверы MySQL настроены так, что к ним можно получить доступ только с локального хоста из соображений безопасности.

person Pekka    schedule 12.01.2010
comment
Стоит отметить, что некоторые серверы MySQL настроены таким образом, что не привязываются к общедоступному интерфейсу. Точно так же, если вы хотите ограничить приложение PHP таким же образом, вам следует подумать об обслуживании его через экземпляр apache, привязанный только к внутреннему интерфейсу. - person Frank Farmer; 13.01.2010

Извините, но все эти ответы кажутся мне ужасными. Я бы предложил перефразировать вопрос, потому что в некотором смысле все машины являются «локальными».

Вопрос должен быть; Как запустить разные пути кода в зависимости от того, на какой машине он выполняется.

На мой взгляд, самый простой способ - создать файл с именем DEVMACHINE или как вы хотите, а затем просто проверить

file_exists('DEVMACHINE')

Не забудьте исключить этот файл при загрузке в среду живого хостинга!

Это решение не зависит от конфигурации сети, его нельзя подделать и оно позволяет легко переключаться между работающим «живым кодом» и «дев-кодом».

person Daniklad    schedule 26.04.2019

Кажется, вам не следует использовать $_SERVER['HTTP_HOST'], потому что это значение в заголовке http, которое легко подделать.

Вы также можете использовать $_SERVER["REMOTE_ADDR"], это более безопасное значение, но его также можно подделать. Этот remote_addr является адресом, на который Apache возвращает результат.

person nicola    schedule 26.04.2011
comment
REMOTE_ADDR можно подделать, однако, если вы хотите подделать его как 127.0.0.1 или ::1, для этого потребуется скомпрометировать машину, а поддельный REMOTE_ADDR - наименьшая из ваших забот. Соответствующий ответ - stackoverflow.com/a/5092951/3774582 - person Goose; 16.11.2016

Если вы хотите иметь белый/белый список, который поддерживает статические IP-адреса и динамические имена.

Например:

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

Таким образом, вы можете составить список имен/IP-адресов, которые можно будет (наверняка) обнаружить. Динамические имена добавляют больше гибкости для доступа из разных точек.

Здесь у вас есть два общих варианта: вы можете задать имя в своем файле локальных хостов или просто использовать один поставщик динамических имен, который можно найти где угодно.

Эта функция CACHES приводит к тому, что функция 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 упомянул в своем опубликовать как "этот вопрос о вознаграждении"

person Heroselohim    schedule 03.10.2014
comment
Я не знаю, почему кто-то поставил отрицательную оценку моему ответу, хотя он явно предлагает динамическое разрешение имен, а другие нет. Разрешение DNS медленное, поэтому требуется разрешение кэширования. - person Heroselohim; 21.03.2016

Как насчет сравнения $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR'], чтобы определить, находится ли клиент на той же машине, что и сервер?

person Eugen Wesseloh    schedule 05.05.2017
comment
$_SERVER['SERVER_ADDR'] не всегда надежно возвращает адрес сервера, например, при использовании балансировщиков нагрузки он возвращает IP-адрес балансировщика нагрузки, я полагаю. - person Mike W; 29.08.2018

Использовал это простое условие PHP

if($_SERVER['HTTP_HOST'] == 'localhost')
{
    die('Localhost');
}
person Sandeep Sherpur    schedule 28.02.2021

Я нашел простой ответ.

Потому что все локальные диски имеют 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';
}
person Scoobeedo Cool    schedule 03.03.2017
comment
Это решение кажется довольно восприимчивым к ошибкам и работает только в Windows. - person Husky; 08.10.2020