2015-04-24 11 views
7

Pracowałem z HttpFox i porównałem wartości (dane url i post) z tymi, które wygenerował mój kod. Są całkowicie takie same, ale zawsze widzę komunikat "Logowanie nie powiodło się" na stronie. Nie mam pojęcia, jaki może być problem.PHP cIRC Authentication Issue

Kod:

require 'domparser_1_5/simple_html_dom.php'; 

$username = "username"; 
$password = "password"; 

function login($url,$data){ 
    $fp = fopen("cookie.txt", "w"); 
    fclose($fp); 
    $login = curl_init(); 
    curl_setopt($login, CURLOPT_URL, $url); 
    curl_setopt($login, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($login, CURLOPT_COOKIEJAR, "cookie.txt"); 
    curl_setopt($login, CURLOPT_COOKIEFILE, "cookie.txt"); 
    curl_setopt($login, CURLOPT_TIMEOUT, 40000); 
    curl_setopt($login, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($login, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); 
    curl_setopt($login, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($login, CURLOPT_POST, true); 
    curl_setopt($login, CURLOPT_POSTFIELDS, $data); 
    ob_start(); 
    $result = curl_exec($login); 
    ob_end_clean(); 
    curl_close($login); 
    unset($login); 
    return $result; 
} 

function generate_pass($user, $password, $token) { 
    if ($password) { 
     $enc_pass = md5($password); 
     $pass = $user.':'.$enc_pass.':'.$token; 
     return md5($pass); 
    } 
} 

function get_token() { 
    $html = file_get_html('https://www.foo.com/'); 
    $token = ""; 
    foreach($html->find('input') as $element) { 
     if($element->name == "token") { 
      $token = $element->value; 
     } 
    } 
    if (!$token) { 
     die('No token found'); 
    } 
    return $token; 
} 

$token = get_token(); 

echo login("https://www.foo.com/login/start.html", "user=".$username."&password=".$password."&submit=Anmelden&logintype=login&pid=4%2C93%2C1828&pass=".generate_pass($username, $password, $token)."&redirect_url=login%2Fstart.html&tx_felogin_pi1%5Bnoredirect%5D=0&token=".$token.""); 
+0

Spróbuj użyć biblioteki Guzzle, jest bardziej przyjazna dla użytkownika. https://github.com/guzzle/guzzle – vanadium23

+0

Lub możesz dodać Postman Plugin (https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm), wysłać swoją prośbę i sprawdzić, czy to naprawdę działa ... –

+0

Dlaczego masz kod po 'return curl_exec ($ login);'? Funkcja kończy się, gdy użyjesz 'return'. – Barmar

Odpowiedz

1

uwierzytelnianie nie powiedzie się z powodu niedopasowania pomiędzy token i ciasteczka (ów) minął.

Po załadowaniu strony w celu pobrania tokena z get_token() serwer wysyła plik cookie, którego nie zapisujesz.

Później, przy próbie zalogowania się serwer oczekuje na otrzymanie tego samego pliku cookie, który wysłał, gdy otrzymałeś numer token. Ale nie wysyłasz tego.

Proponuję przepisanie get_token() za pomocą loków i przechowywanie plików cookie w cookie.txt. To pozwoli Ci przekazać je później, kiedy będziesz dzwonić login()

tak:

function get_token() { 
    $url = 'https://www.foo.com/'; 
    $curl = curl_init(); 
    curl_setopt($curl, CURLOPT_URL, $url); 
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($curl, CURLOPT_COOKIEJAR, "cookie.txt"); 
    curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt"); 
    curl_setopt($curl, CURLOPT_TIMEOUT, 40000); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); 
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); 
    $result = curl_exec($curl); 
    curl_close($curl); 
    unset($curl); 

    $html = str_get_html($result); 
    $token = ""; 
    foreach($html->find('input') as $element) { 
     if($element->name == "token") { 
      $token = $element->value; 
     } 
    } 
    if (!$token) { 
     die('No token found'); 
    } 
    return $token; 
} 

Ważne:

Usuń

$fp = fopen("cookie.txt", "w"); 
fclose($fp); 

Od login() jak obcina do zera bajtów pliku cookie.txt, a ty nie chcesz usuwać pliku cookie odkopał.

Należy pamiętać, że curl_exec() tworzy plik cookie o specjalnej nazwie, jeśli nie istnieje.

+0

Okay, to brzmi logicznie. Czy możesz podać mi fragment kodu, jak to zrobić? – user289520

+0

Zasadniczo łączysz funkcję 'login' bez przekazywania danych postów i oryginalnego' get_token' używając 'str_get_html' do inicjowania parsowania html. Opublikowalem fragment. Oczywiście zakładam, że reszta kodu (otrzymujesz token z htm, jak przekazujesz login i przekazujesz na stronę) jest poprawna.** Imprortant ** nie obcina 'cookie.txt' do' login() 'zobacz odpowiedź – Paolo

+0

Również ... pobierz token. Przechowuj w zmiennej. Następnie wygeneruj hasło. Następnie zaloguj się. Zapobiega to dwukrotnemu załadowaniu strony głównej. – Paolo