Hi everybody !

I have this current problem .. I need to login into a website via cUrl .. website : www.v-tac [dot] ro/

Now based on the headers and based on the input fields I wrote a php function, but I hit a wall with the token .

HEADERS :

username=username&password=password&Submit=Conectare&option=com_users&task=user.login&return=aW5kZXgucGhwP0l0ZW1pZD0yMTY%3D&0dbf64fe20e2395a7d72ed5b64b3cf7c=1
function login_to_website($targetURL){

global $browser_user_agent;
if(empty($targetURL)) { return; }
if(empty($login_url)) { $login_url = $targetURL; }
$url = $login_url;

$login_user     = "loginusername";
$login_password = "loginpassword";
$thetoken       = "this-is-my-problem-the-token-from-the-hidden-input";        

$post_data = array();   
$post_data['username']  = "$login_user"; 
$post_data['password']  = "$login_password"; 
$post_data['Submit']    = "Conectare";
$post_data['option']    = "com_users";
$post_data['task']      = "user.login";
$post_data['return']    = "aW5kZXgucGhwP0l0ZW1pZD0yMTY%3D";
$post_data[$thetoken]   = "1";          

$postthis = http_build_query($post_data);

$login = curl_init();

curl_setopt($login, CURLOPT_COOKIEJAR, dirname(__FILE__) . "/cookie.tmpz");
curl_setopt($login, CURLOPT_COOKIEFILE, dirname(__FILE__) . "/cookie.tmpz");
curl_setopt($login, CURLOPT_VERBOSE, true);
curl_setopt($login, CURLOPT_URL, $url);
curl_setopt($login, CURLOPT_USERAGENT, random_user_agent());
curl_setopt($login, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($login, CURLOPT_RETURNTRANSFER, TRUE);  
curl_setopt($login, CURLOPT_POST, TRUE);
$timeout = 5;
curl_setopt( $login, CURLOPT_CONNECTTIMEOUT, $timeout );
curl_setopt( $login, CURLOPT_TIMEOUT, $timeout );
curl_setopt( $login, CURLOPT_MAXREDIRS, 10 );   

curl_setopt($login, CURLOPT_POSTFIELDS, $postthis); // POST vars

curl_setopt($login, CURLOPT_HEADER, 0); // debug headers sent - 1

  $data = curl_exec ($login);

  curl_setopt($login, CURLOPT_URL, $targetURL);

  $datax = curl_exec ($login);
  return $datax;

  // close cURL resource, and free up system resources
  curl_close($login);
}

The problem is this the last two array inputs, i just made a copy paste .. but the token is generated each time the page is loaded, located on the page as an input hidden field .

So the question is how do I get a fresh token that will work ?

    hanisnl;11043209 wrote:

    So the question is how do I get a fresh token that will work ?

    Think about how you did that the first time (without PHP). Break that down into a series of actions, such as:

    1. Retrieved the login page.

    2. Searched the source code of the retrieved content for the appropriate login form.

    3. Within that form, searched for the (what I assume to be) hidden <input> element containing the CSRF token value that was generated for this request.

    4. From that <input> element, extracted its value.

    Right? Change each of those steps into one or more PHP statements, and there's your answer.

    Alternatively, since screen-scraping is one of the worst methods (IMHO) of obtaining external data, you could try contacting the owners of that website to see if there is some sort of computer-friendly API that would better suit your needs.

      well i did that .. used xpath to obtain the value, but it does not work .

      and, i did ask the owners for the content, as they are one of the suppliers, but they just don't care how I take the info and they do not have it in any other form ..so they say ...

        hanisnl;11043219 wrote:

        well i did that .. used xpath to obtain the value

        What does your code look like? And what does the html of the page you scrape look like. Or perhaps you could post its url?

        hanisnl;11043219 wrote:

        , but it does not work .

        in what way? php errors? nothing retrieved? token retrieved, but&#8230;?

          well to get the token form the page i used wrote this :

          	$htmlx = file_get_contents('http://www.v-tac.ro');
          	$htmlx = mb_convert_encoding($htmlx, 'UTF-8', mb_detect_encoding($htmlx)); //make sure this is utf8
          	if(!strlen($htmlx)) {echo "No HTML here . stoping execution ."; return;}
          	$doc = new DomDocument;
          	@$doc->loadHTML($htmlx);
          	$xpath = new DOMXPath($doc);
          
          echo $xpath->query('//fieldset[@class="userdata"]/input[5]')->item(0)->getAttribute("name");
          $thetoken = $xpath->query('//fieldset[@class="userdata"]/input[5]')->item(0)->getAttribute("name");

          I do get the token, but the response is : TOKEN INVALID .

          Ps: i did post the url in the first post message, also it's in the above xPath php code / file_get_contents

            1. Please post the html code of the element you believe your xpath query will match?

            2. Also please post the value returned by ->getAttribute("name"); for the element retrieved by your xpath query?

              You belive that I've done something wrong ?.. it's no problem, here is the HTML code I'm parsing with xPath :

              	<fieldset class="userdata">
              
              <p id="form-login-username">
              	<label for="modlgn-username">Nume Utilizator</label>
              	<input id="modlgn-username" type="text" name="username" class="inputbox" size="18">
              </p>
              <p id="form-login-password">
              	<label for="modlgn-passwd">Parola</label>
              	<input id="modlgn-passwd" type="password" name="password" class="inputbox" size="18">
              </p>
              	<p id="form-login-remember">
              	<label for="modlgn-remember">Retine utilizator</label>
              	<input id="modlgn-remember" type="checkbox" name="remember" class="inputbox" value="yes">
              </p>
              
              <input type="submit" name="Submit" class="button" value="Conectare">
              <input type="hidden" name="option" value="com_users">
              <input type="hidden" name="task" value="user.login">
              <input type="hidden" name="return" value="aW5kZXgucGhwP0l0ZW1pZD0yMTY=">
              <input type="hidden" name="11b09608b3184e6258012d44846c81ed" value="1">	
              
              </fieldset>

                as you can see the ->getAttribute("name"); is the last input / hidden input and the xpath part works with no problem .

                the problem is, whatever i do, I can not pass that generated token aka the last hidden input .

                and the result is : invalid token .

                and it's mandatory to get the html result as an authenticated user, or the page does not contain all the product tech information and price ...

                  Ah, I missed the line with

                   $post_data[$thetoken]   = "1";           

                  and thought you assigned the value of

                  $xpath->query('//fieldset[@class="userdata"]/input[5]')->item(0)->getAttribute("name"); 
                  

                  to the 'return' field.

                  The problem is that when you call curl_exec, you will be initiating a new session for which the previously received token has no meaning. If you look at the initial page request/response in a browser (with cookies cleared) you will find

                  Set-Cookie:64d112cd74785e7519c97b974b7eb6bb=b6ee58c6387d37e5fe81e4863ed897cb; path=/
                  

                  The solution is to ditch file_get_contents and fetch the page using curl. Then reuse the same connction handle to post the form.

                    i can NOT believe i missed that !

                    it works ... OMG ! .. thanks for pointing that out to me ... i don't even use file_get_contents ... i use curl .. i don't know how that got in the mix ... i think testing got me in this mess ...

                    anyway, great ! thanks a lot !

                      Write a Reply...