2010-06-03 10 views
7

J'ai implémenté une fonction qui s'exécute sur chaque page que je veux restreindre des utilisateurs non connectés. La fonction redirige automatiquement le visiteur vers la page de connexion dans le cas où il n'est pas connecté.PHP: Vérifiez si URL redirige?

Je voudrais créer une fonction PHP exécutée à partir d'un serveur exernal et itérer via un certain nombre d'URL définies (tableau avec les URL pour chaque site protégé) pour voir s'ils sont redirigés ou non. Ainsi, je pourrais facilement m'assurer que la protection est activée sur chaque page.

Comment cela a-t-il pu être fait?

Merci.

+0

redirigée comment? Appelé de quel client? Lorsque vous êtes connecté ou non connecté? Pourquoi? Le script doit-il gérer les cookies de session et d'autres choses compliquées? –

+0

Définir "URL redirigé" s'il vous plaît. –

+0

Voir [Comment puis-je déterminer si une URL redirige en PHP?] (Http://stackoverflow.com/questions/427203/how-can-i-determine-if-a-url-redirects-in-php/481377# 481377) –

Répondre

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

Super solution sucrée! Tack Adam :) – Industrial

+2

Vous pouvez également utiliser curl_getinfo ($ ch, CURLINFO_HTTP_CODE) pour lire le code d'état (301 ou 302) – baloo

+2

Vous pouvez également économiser de la bande passante et de la puissance de traitement si vous utilisez curl_setopt ($ handle, CURLOPT_NOBODY, true); '. Cela enverra uniquement une requête HTTP HEAD. De cette façon, vous n'aurez pas à couper le corps. Voir aussi cet article: http://schlitt.info/opensource/blog/0606_sending_head_requests_with_extcurl.html – chiborg

-2

Je ne comprends pas votre question. Vous avez un tableau avec des URL et vous voulez savoir si l'utilisateur provient de l'une des URL répertoriées? Si je ne me trompe pas dans la compréhension de votre quête:

$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

le référent est faible –

+0

Mise à jour de la question. Je veux appeler chaque URL de mon tableau pour voir si elles restent à l'URL définie ou redirige vers la page de connexion. – Industrial

0

Vous pouvez utiliser la session, si le tableau de session n'est pas défini, l'URL redirigé vers une page de connexion. .

+0

C'est ainsi que ma sécurité est essentiellement basée, mais ne me permet pas de voir si une page d'un tableau redirige ou non. – Industrial

1

Je ne suis pas sûr si cela a vraiment du sens comme un contrôle de sécurité.

Si vous vous inquiétez que des fichiers soient appelés directement sans votre "l'utilisateur est-il connecté?" les contrôles en cours d'exécution, vous pouvez faire ce que beaucoup de grands projets PHP font: Dans le fichier d'inclusion central (où la vérification de sécurité est en cours) définir une constante BOOTSTRAP_LOADED ou autre, et dans chaque fichier, vérifier si cette constante est définie.

Les tests sont excellents et les tests de sécurité sont encore meilleurs, mais je ne suis pas sûr du type de défaut que vous cherchez à découvrir? Pour moi, cette idée est comme une perte de temps qui n'apportera aucune réelle sécurité supplémentaire.

Assurez-vous que votre script die() s après la redirection header("Location:..."). Cela est essentiel pour empêcher l'affichage de contenu supplémentaire après la commande header (un die() manquant ne sera pas intercepté par votre idée, car l'en-tête de redirection sera toujours émis ...)

Si vous vraiment envie de faire cela, vous pouvez également utiliser un outil comme wget et le nourrir une liste d'URL. Demandez-lui d'aller chercher les résultats dans un répertoire et de vérifier (par exemple en regardant les tailles de fichiers qui devraient être identiques) si chaque page contient la boîte de dialogue de connexion. Pour ajouter une autre option ...

1

Voulez-vous vérifier le code HTTP pour voir s'il s'agit d'une redirection?

$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

J'ai modifié la réponse d'Adam Backstrom et implémenté la suggestion de chiborg. (Télécharger uniquement HEAD). Il a une chose de plus: Il vérifiera si la redirection est dans une page du même serveur ou est dehors. Exemple: terra.com.br redirige vers terra.com.br/portal. PHP va le considérer comme une redirection, et c'est correct. Mais je voulais seulement lister cette URL qui redirige vers une autre URL. Mon anglais n'est pas bon, donc, si quelqu'un a trouvé quelque chose de vraiment difficile à comprendre et peut le modifier, vous êtes le bienvenu.

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

Vous pouvez toujours essayer d'ajouter:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

depuis 302 signifie qu'il déplacé, permettre à l'appel boucle à suivre et retourner quelles que soient les retours d'URL déplacés.

+0

CELA ... est en fait la bonne réponse. Je vous remercie! Il semble que sans cette boucle s'arrête au contenu qu'il reçoit d'abord et ne suit pas la redirection s'il y en a une. Je vous remercie!!! –

3

Je CURL et ne prends que les en-têtes, après que je compare mon URL et url de boucles d'en-tête:

   $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"; 
       } 
Questions connexes