2010-06-03 18 views
7

Implementé una función que se ejecuta en cada página que deseo restringir a usuarios que no iniciaron sesión. La función redirige automáticamente al visitante a la página de inicio de sesión en caso de que no haya iniciado sesión.PHP: ¿verifica si la URL redirige?

Me gustaría hacer una función de PHP que se ejecute desde un servidor de ejercicios e itere a través de varias URL establecidas (array con URL que es para cada sitio protegido) para ver si son redirigidos o no. De este modo, podría asegurarme fácilmente si la protección está funcionando en todas las páginas.

¿Cómo puede hacerse esto?

Gracias.

+0

redirigidas cómo? Llamado de qué cliente? ¿Cuándo inicias sesión o cuando no estás conectado? ¿Para qué? ¿El guión tendrá que manejar las cookies de sesión y otras cosas complicadas? –

+0

Defina "URL redirigida" por favor. –

+0

Ver [¿Cómo puedo determinar si una URL redirige en PHP?] (Http://stackoverflow.com/questions/427203/how-can-i-determine-if-a-url-redirects-in-php/481377# 481377) –

Respuesta

21
$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>"; 
} 
+0

¡Solución súper dulce! Tack Adam :) – Industrial

+2

También puede usar curl_getinfo ($ ch, CURLINFO_HTTP_CODE) para leer el código de estado (301 o 302) – baloo

+2

También puede ahorrar algo de ancho de banda y poder de procesamiento si usa 'curl_setopt ($ handle, CURLOPT_NOBODY, true); '. Esto solo enviará una solicitud HTTP HEAD. De esta forma no tendrás que cortar el cuerpo. Ver también este artículo: http://schlitt.info/opensource/blog/0606_sending_head_requests_with_extcurl.html – chiborg

-2

No entiendo su pregunta. ¿Tiene una matriz con URL y desea saber si el usuario proviene de una de las URL enumeradas? Si estoy en lo correcto en la comprensión de su búsqueda:

$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'; 
} 
+0

el intermediario es débil –

+0

Se ha actualizado la pregunta. Deseo llamar a todas las urls de mi matriz para ver si permanecen en la url configurada o redirecciona a la página de inicio de sesión. – Industrial

0

Usted puede utilizar la sesión, si la matriz de sesión no está establecido, el URL redirigido a una página de inicio de sesión. .

+0

Así es como mi seguridad se basa básicamente, pero no me permitirá ver si una página de una matriz redirige o no. – Industrial

1

no estoy seguro de si esto realmente tiene sentido como un control de seguridad.

Si está preocupado acerca de los archivos recibiendo llamadas directamente sin su "el usuario se registra en?" cheques que se ejecutan, puede hacer lo que hacen muchos proyectos grandes de PHP: en el archivo de inclusión central (donde se realiza la comprobación de seguridad) defina una constante BOOTSTRAP_LOADED o lo que sea, y en cada archivo, verifique si esa constante está configurada.

La prueba es grande y las pruebas de seguridad es aún mejor, pero no estoy seguro de qué tipo de defecto que busca descubrir con esto? Para mí, esta idea se siente como una pérdida de tiempo que no traerá ninguna seguridad adicional real.

Solo asegúrese de que su script die() s después del redireccionamiento header("Location:..."). Esto es esencial para evitar que se muestre contenido adicional después del comando de encabezado (un dado perdido() no será capturado por su idea por cierto, ya que el encabezado de redirección aún se emitirá ...)

Si Realmente quiero hacer esto, también puede usar una herramienta como wget y darle una lista de URL. Haga que busque los resultados en un directorio y verifique (por ejemplo, mirando los tamaños de archivo que deberían ser idénticos) si cada página contiene el cuadro de diálogo de inicio de sesión. Solo para agregar otra opción ...

1

¿Desea verificar el código HTTP para ver si se trata de una redirección?

$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 
     } 
    } 
0

Modifiqué la respuesta de Adam Backstrom e implementé la sugerencia de chiborg. (Descargar solo HEAD). Tiene una cosa más: comprobará si la redirección está en una página del mismo servidor o está fuera. Ejemplo: terra.com.br redirige a terra.com.br/portal. PHP lo considerará como redirigir, y es correcto. Pero solo quería enumerar esa URL que redirecciona a otra URL. Mi inglés no es bueno, entonces, si alguien encuentra algo realmente difícil de entender y puede editar esto, de nada.

function RedirectURL() { 
    $urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/'); 

    foreach ($urls as $url) { 
     $ch = curl_init(); 

     curl_setopt($ch, CURLOPT_HEADER, true); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
     // chiborg suggestion 
     curl_setopt($ch, CURLOPT_NOBODY, true); 

     // ================================ 
     // READ 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); 
     echo $out; 

     $headers = explode("\n", $out); 

     foreach($headers as $header) { 
      if(substr(strtolower($header), 0, 9) == "location:") { 
       // read URL to check if redirect to somepage on the server or another one. 
       // terra.com.br redirect to terra.com.br/portal. it is valid. 
       // but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid. 
       // what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page. 

       // if contains http, we will check if changes url or not. 
       // some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden 

       // only execute if have http on location 
       if (strpos(strtolower($header), "http") !== false) { 
        $address = explode("/", $header); 

        print_r($address); 
        // $address['0'] = http 
        // $address['1'] = 
        // $address['2'] = www.terra.com.br 
        // $address['3'] = portal 

        echo "url (address from array) = " . $url . "<br>"; 
        echo "address[2] = " . $address['2'] . "<br><br>"; 

        // url: terra.com.br 
        // address['2'] = www.terra.com.br 

        // check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here. 
        if(strpos(strtolower($address['2']), strtolower($url)) !== false) { 
         echo "URL NOT REDIRECT"; 
        } else { 
         // not the same. (areiaebrita) 
         echo "SORRY, URL REDIRECT WAS FOUND: " . $url; 
        } 
       } 
      } 
     } 
    } 
} 
0
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; 
} 
2

Siempre se puede intentar añadir:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

desde 302 significa que se movió, permitir que la llamada rizo a seguirlo y volver cualesquiera que sean las declaraciones de URL movido.

+0

ESTA ... es en realidad la respuesta correcta. ¡Gracias! Parece que sin este rizo se detiene en el contenido que primero recibe y no sigue el redireccionamiento si hay uno. ¡¡¡Gracias!!! –

3

utilizo rizo y sólo tomo cabeceras, después comparo mi URL y URL de rizo cabecera:

   $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){ 
        $status = "not redirect"; 
       }else { 
        $status = "redirect"; 
       } 
Cuestiones relacionadas