PHP: проверить, перенаправляет ли URL? - PullRequest
9 голосов
/ 03 июня 2010

Я реализовал функцию, которая запускается на каждой странице, которую я хочу запретить входить не зарегистрированным пользователям. Функция автоматически перенаправляет посетителя на страницу входа в случае, если он или она не вошли в систему.

Я хотел бы создать функцию PHP, которая запускается с внешнего сервера и выполняет итерацию по ряду установленных URL-адресов (массив с URL-адресами для каждого защищенного сайта), чтобы увидеть, перенаправлены они или нет. Таким образом, я мог легко убедиться, что защита включена и работает на каждой странице.

Как это можно сделать?

Спасибо.

Ответы [ 9 ]

25 голосов
/ 03 июня 2010
$urls = array(
    'http://www.apple.com/imac',
    'http://www.google.com/'
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

foreach($urls as $url) {
    curl_setopt($ch, CURLOPT_URL, $url);
    $out = curl_exec($ch);

    // line endings is the wonkiest piece of this whole thing
    $out = str_replace("\r", "", $out);

    // only look at the headers
    $headers_end = strpos($out, "\n\n");
    if( $headers_end !== false ) { 
        $out = substr($out, 0, $headers_end);
    }   

    $headers = explode("\n", $out);
    foreach($headers as $header) {
        if( substr($header, 0, 10) == "Location: " ) { 
            $target = substr($header, 10);

            echo "[$url] redirects to [$target]<br>";
            continue 2;
        }   
    }   

    echo "[$url] does not redirect<br>";
}
4 голосов
/ 03 августа 2016

Я использую curl и беру только заголовки, после того как я сравнил свой url и url из заголовка curl:

                $url="http://google.com";
                $ch = curl_init();

                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
                curl_setopt($ch, CURLOPT_HEADER, 1);
                curl_setopt($ch, CURLOPT_NOBODY, 1);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                $res = curl_exec($ch);

                if(curl_getinfo($ch)['url'] == $url){
                    echo "not redirect";
                }else {
                    echo "redirect";
                }
3 голосов
/ 15 июля 2014

Вы всегда можете попробовать добавить:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

, поскольку 302 означает, что он перемещен, разрешите вызову curl следовать за ним и вернуть то, что возвращает перемещенный URL.

1 голос
/ 03 июня 2010

Хотите проверить HTTP-код, чтобы убедиться, что это перенаправление?

    $params = array('http' => array(
        'method' => 'HEAD',
        'ignore_errors' => true
    ));

    $context = stream_context_create($params);
    foreach(array('http://google.com', 'http://stackoverflow.com') as $url) {
      $fp = fopen($url, 'rb', false, $context);
      $result = stream_get_contents($fp);

      if ($result === false) {
          throw new Exception("Could not read data from {$url}");
      } else if (! strstr($http_response_header[0], '301')) {
          // Do something here
      }
    }
1 голос
/ 03 июня 2010

Я не уверен, имеет ли это смысл проверки безопасности.

Если вы беспокоитесь о том, что файлы будут вызываться напрямую без вашего "пользователя вошли в систему?" при выполнении проверок вы можете делать то, что делают многие крупные PHP-проекты: в центральном включаемом файле (где выполняется проверка безопасности) задайте константу BOOTSTRAP_LOADED или что угодно, и в каждом файле проверяйте, установлена ​​ли эта константа.

Тестирование - это здорово, а тестирование безопасности - еще лучше, но я не уверен, какой недостаток вы ищете для этого? Для меня эта идея кажется пустой тратой времени, которая не принесет никакой дополнительной безопасности.

Просто убедитесь, что ваш скрипт die() s после header("Location:...") перенаправления. Это важно для того, чтобы не отображать дополнительный контент после команды заголовка (кстати, по вашей идее не будет замечен отсутствующий die (), так как заголовок редиректа все равно будет выдан ...)

Если вы действительно хотите это сделать, вы также можете использовать такой инструмент, как wget и передать ему список URL-адресов. Пусть он извлечет результаты в каталог и проверит (например, просмотрев размеры файлов, которые должны быть одинаковыми), содержит ли каждая страница диалог входа в систему. Просто чтобы добавить еще один вариант ...

0 голосов
/ 02 июня 2013
function unshorten_url($url){
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    $out = curl_exec($ch);

    $real_url = $url;//default.. (if no redirect)

    if (preg_match("/location: (.*)/i", $out, $redirect))
        $real_url = $redirect[1];

    if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
        $real_url = unshorten_url($real_url);

    return $real_url;
}
0 голосов
/ 23 сентября 2012

Я изменил ответ Адама Бэкстрома и внедрил предложение Чиборга.(Скачать только HEAD).Есть еще одна вещь: он проверит, находится ли перенаправление на странице того же сервера или нет.Пример: terra.com.br перенаправляет на terra.com.br/portal.PHP будет рассматривать это как перенаправление, и это правильно.Но я только хотел перечислить тот URL, который перенаправляет на другой URL.Мой английский не очень хороший, поэтому, если кто-то нашел что-то действительно сложное для понимания и может это отредактировать, пожалуйста.

0 голосов
/ 03 июня 2010

Вы можете использовать сеанс, если массив сеансов не задан, URL-адрес перенаправляется на страницу входа. ,

0 голосов
/ 03 июня 2010

Я не могу понять ваш вопрос. У вас есть массив с URL-адресами, и вы хотите знать, принадлежит ли пользователь одному из указанных URL-адресов? Если я правильно понял ваш квест:

$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
 echo 'FROM ARRAY';
} else {
 echo 'NOT FROM ARR';
}
...