• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 732
  • Last Modified:

PHP POST Request without cURL

I'm trying to send a post request to login to the website below using the following code:

<?php
$post=array(
            'username'=>'blah',
            'password'=>'mypass',
            'u'=>'cal.php',
            'action' => 'Login'
);

$header=array(
                "Content-type"=>"application/x-www-form-urlencoded"
                ,"Content-length"=>strlen(http_build_query($post))
                ,"Referer"=>"http://www.myepisodes.com"
           );

$context_options=array(
                'http'=>array(
                                'method'=>'POST'
                                ,'header'=>$header
                                ,'content'=>http_build_query($post)
                        )
);

$context = stream_context_create($context_options);
$page=file_get_contents('http://www.myepisodes.com/login.php',false,$context);
echo $page;
?>

Any ideas why this doesn't work? It all seems fine to me.
I don't want any other methods / other code snippets pasted here as an answer.
I don't want to be told to use cURL etc, I just want to know exactly why this code above isn't working and how I can fix it.
0
igni7e
Asked:
igni7e
  • 6
  • 6
  • 2
2 Solutions
 
Beverley PortlockCommented:
Looks to me like you are not building the $header variable correctly. It should be a string not an array. See if the attached snippet works any better for you.


<?php
$post=array(
            'username'=>'blah',
            'password'=>'mypass',
            'u'=>'cal.php',
            'action' => 'Login'
);

$header =       "Content-type: application/x-www-form-urlencoded\r\n".
                "Content-length: ". strlen(http_build_query($post)). "\r\n" . 
                "Referer: http://www.myepisodes.com\r\n";
          

$context_options=array(
                'http'=>array(
                                'method'=>'POST'
                                ,'header'=>$header
                                ,'content'=>http_build_query($post)
                        )
);

$context = stream_context_create($context_options);
$page=file_get_contents('http://www.myepisodes.com/login.php',false,$context);
echo $page;
?>

Open in new window

0
 
igni7eAuthor Commented:
I've just tried your code but it didn't work.

I've tested my post vars and they output fine when I submit them to my test webpage so I do think it could be the headers.

Initially I had the headers as strings and then put them into an array to see if that would fix the problem as I saw that solution in another post.

But neither ways work for me. Maybe the headers are incorrect or need additional info? I'm not sure.
At the moment I just echo the login form page instead of the cal.php page content as it doesn't login correctly.
0
 
Beverley PortlockCommented:
When you say "it doesn't work", is  the error the same or has something changed? In what way does it not work?

I've tried it and it echoes the login page with the text fields filled in but with an error of "Wrong username/password", which is hardly surprising.

Have you checked that the php.ini setting of allow_url_fopen is OK?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
igni7eAuthor Commented:
If I change my pw to an incorrect value i get the "Wrong username/password" error you see.
If I correct the pw to my own, I get that exact same page you see minus the "Wrong username/password " text.

In other words, it's not logging in and going to the cal.php page, its just showing the login page instead of logging in.

I assume my allow_url_fopen setting is fine as I'm getting the returned page.
0
 
Beverley PortlockCommented:
OK - Why not add

phpinfo(32);

to the page and look at what variables are passed when you attempt your remote login via the script. That will at least let you see the variables that are being passed and you can look at the login script and see what it does with the values being passed and how it processes them

Phpinfo(32) will not reveal the configuration values that phpinfo normally displays so it is somewhat safer then the usual usage but even so, don't leave it up too long.

0
 
Beverley PortlockCommented:
BTW, when I say "OK - Why not add phpinfo(32); to the page" I mean login.php
0
 
igni7eAuthor Commented:
The login.php is not my website.
I substituted login.php to my own test.php page and printed out all $_POST varialbes to ensure they are being sent properly and they are.

I'm not sure what's wrong - I've tried this with numerous websites and it doesn't work, but when I create a basic html page with input fields (nothing but input name/value and form action) and submit it, it works fine. This php post request should work the same way.

0
 
Ray PaseurCommented:
"I don't want to be told to use cURL"

Why not - that is what CURL is for!  You might also consider fsockopen().  One probability here is that the login page puts a cookie on the browser (perhaps a session cookie), so if you want to login, you will have to write a program that acts like a well-behaved HTTP client.

Let us know if you change your mind about CURL - I can show you how I log into web sites with CURL.

bet wishes for the new year, ~Ray
0
 
igni7eAuthor Commented:
I'd rather find out what the problem I'm having is, but that looks unlikely so I'll give cURL a go.

I don't like cURL because it's long, seems inefficient and it requires the cURL library.
Would you be able to post cURL code with as much bloat removed as possible?
The core info I'm interested in is:
Where to put <input> name/value info
How to keep login session info and post another request to a different page of the same website.

I'm also not sure how I'd go about putting the cURL library on my webserver.
0
 
Beverley PortlockCommented:
"The login.php is not my website."
Ah! I assumed that you had control of both pages. In that case Ray is probably right. On many websites, session cookies are set as a matter of course - particularly if you are intending to login as a session variable is often used to confirm a successful login.

"I'm also not sure how I'd go about putting the cURL library on my webserver."

Do a phpinfo() and look for a section marked "cURL". It may be installed already.

Failing that, if you have control of this web server then use your repository manager to install php5-curl. For instance on a Debian based distro

sudo apt-get install php5-curl

On SuSE use Yast, on Redhat it is (I think)

yum install php5-curl

0
 
igni7eAuthor Commented:
Thanks, I have it already installed:
      libcurl/7.19.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

Is it necessary for me to store session cookies, or can I just post their data on the fly when sending the next request?

I'm still not sure why my code above didnt work, my understanding is that when I send my post request, the server will return the page that I want and would only need session cookie info when I submit another request, not for my initial one as that sends login info to get the session cookie.
0
 
Ray PaseurCommented:
To get CURL working with PHP, follow the instructions on the pages linked here:
http://us3.php.net/manual/en/curl.setup.php

regarding this: "I don't like cURL because it's long, seems inefficient" not sure I agree with that assessment.  The central issue most of us have with CURL is that it takes considerable experience to use it correctly.   That said, it is easy to "can" in a function call.

Read this over - code and comments - and post back here if you do not understand anything.  It is a teaching sample, far from complete, but for many web sites it can be easily adapted to let you log in and access the password protected pages.

Best, ~Ray

<?php // RAY_curl_login.php
error_reporting(E_ALL);
echo "<pre>\n";

// THE REPLACEMENTS (CASE SENSITIVE) ARE THE LOGIN CREDENTIALS FOR THE FORUM
$replacements["UserName"] = 'YourUID';
$replacements["Password"] = 'YourPWD';

// READ THE FORUM PAGE
$baseurl = 'http://www.myforum.com';

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $baseurl);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR,  'cookie.txt');
curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
$htm=curl_exec($ch);

// REMOVE THE END-OF-LINE CHARACTERS
$htm = str_replace(PHP_EOL, "", $htm);

// ISOLATE THE FORM
$form   = explode("<form",$htm);
$form   = explode("</form>",$form[1]);
$inputs = explode("<input",$form[0]);
$post   = "";

foreach($inputs as $key => $val)
{
    // IDENTIFY THE ACTION SCRIPT
    $action = strpos($val, "action");
    if($action !== false)
	{
	    // EXTRACT THE ACTION SCRIPT NAME FROM THE FORM INPUT
	    $actstart = strpos($val, "\"", $action+1);
	    $actend   = strpos($val, "\"", $actstart+1);
	    $posturl  = substr($val, $actstart+1, ($actend-$actstart-1));
	    continue;
	}

    // IDENTIFY THE INPUT FIELDS BY NAME AND VALUE PAIRS
    $name = strpos($val, "name");
    if($name !== false)
    {
        // EXTRACT THE NAME FROM THE FORM INPUT
        $namestart = strpos($val, "\"", $name+1);
        $nameend   = strpos($val, "\"", $namestart+1);
        $strname   = substr($val, $namestart+1, ($nameend-$namestart-1));

        // EXTRACT THE VALUE
        $value = strpos($val, "value");
        if($value !== false)
        {
            $valuestart = strpos($val, "\"", $value+1);
            $valueend   = strpos($val, "\"", $valuestart+1);
            $strvalue   = substr($val, $valuestart+1, ($valueend-$valuestart-1));
        }

        // IF NO VALUE TRY TO REPLACE
        else
        {
            foreach ($replacements as $k => $v)
            {
                if ($k == $strname) $strvalue = $v;
            }
        }
        $post .= "&" . $strname . "=" . $strvalue;
    }
}

// DECLOP LEFTMOST AMPERSAND
$post=substr($post,1);

// SET THE LOGIN URL
$posturl = $baseurl . '/' . $posturl;

// NOW POST THE DATA WE HAVE FILLED IN
curl_setopt($ch, CURLOPT_URL, $posturl);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

// WAIT A RESPECTABLE PERIOD OF TIME
sleep(1);

// CALL THE WEB PAGE
$xyz = curl_exec($ch);
$err = curl_errno($ch);
$inf = curl_getinfo($ch);
if ($xyz === FALSE)
{
    echo "\nCURL POST FAIL: $posturl CURL_ERRNO=$err ";
    var_dump($inf);
}

// NOW ON TO THE NEXT PAGE
curl_setopt($ch, CURLOPT_URL, 'http://www.forum.com/nextpage');
curl_setopt($ch, CURLOPT_POST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, '');

$xyz = curl_exec($ch);
$err = curl_errno($ch);
$inf = curl_getinfo($ch);
if ($xyz === FALSE)
{
    echo "\nCURL POST FAIL: $posturl CURL_ERRNO=$err ";
    var_dump($inf);
}

// SHOW OFF THE DATA AFTER THE LOGIN
echo ($xyz);

Open in new window

0
 
igni7eAuthor Commented:
Thanks both,
I used the cURL code located here:
http://www.trap17.com/index.php/automatic-login-curl_t38162.html

It's a lot less bloated and easy to understand.

If anyone know what was wrong with my inital code, please let me know.
0
 
Beverley PortlockCommented:
"If anyone know what was wrong with my inital code, please let me know."

Well, we do not know for definite, but I suspect the inability to handle session cookies. Most sites need a session to log you in.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 6
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now