PHP curl - posting asp.net viewstate value
I have the following code to login into an external site application (asp.net app) from a local site login form (written in php):
<?php
$curl_connection = curl_init('www.external.com/login.aspx');
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl_connection, CURLOPT_USERAGENT,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
// Post data array
$post_data['LoginControl$UserName'] = 'ExampleUName';
$post_data['LoginControl$Password'] = 'ExamplePWord';
// Add form fields into an array to get ready to post
foreach ($post_data as $key => $value)
{
$post_items[] = $key . '=' . $value;
}
$post_string = implode ('&', $post_items);
// Tell cURL which string to post
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
// Execute and post
$result = curl开发者_Go百科_exec($curl_connection);
?>
I get directed to the login form of the external site instead of being directed to the application logged in. I think the problem is that I need to pass the viewstate values through, but i'm not sure how to go about doing that?
I don't have control over the external application. But we want users to be able to login to the application through our website, to maintain branding etc.
I've posted a couple of other threads recently about the use of php cURL, but I'm at the stage now where I think the viewstate is the problem ...
Thanks, Mark.
This seems to be a real problem when trying to scrape the asp.net pages.
The pages contain a hidden field named "__VIEWSTATE" which contains a base64 encoded set of va;ues containing some or all of the page state when the page was sent. It usually also contains the SHA1 of the viewstate.
What this means is that your post must contain everything in the _VIEWSTATE or it will fail.
I have been able to post a simple login page that has only 2 fields but not a more complex page in which the author has chosen to put the entire page state in the viewstate.
As yet I have not been able to come up with a solution.
Change:
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
To:
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, false);
You also need to set up a cookie file, take a look at CURLOPT_COOKIEFILE
CURLOPT_COOKIEFILE
:
The name of the file containing the cookie data. The cookie file can be in Netscape format, or just plain HTTP-style headers dumped into a file.
CURLOPT_COOKIE
:
The contents of the "Cookie: " header to be used in the HTTP request. Note that multiple cookies are separated with a semicolon followed by a space (e.g., "fruit=apple; colour=red")
CURLOPT_COOKIEJAR
:
he name of a file to save all internal cookies to when the connection closes.
@see http://www.php.net/manual/en/function.curl-setopt.php
curl_setopt($curl_connection, CURLOPT_COOKIEFILE, 'cookiefile.txt');
curl_setopt($curl_connection, CURLOPT_COOKIEJAR, 'cookiefile.txt');
Don't expect it to work without encoding the __VIEWSTATE string in php using
rawurlencode($viewstate);
I've encountered the same problem recently, so I just leave my way to go about it here, in case someone else stumbles on this thread looking for an answer too.
I solved this by preceding every POST request with a GET request to the same url, and scraping all the input fields into an array of key-value pairs out of the response from that GET. Then I replaced some values in that array (login field values, for example), and sent the whole thing back in the subsequent POST. This way my POST request contained all the valid __VIEWSTATE, __EVENTVALIDATOR and yada-yada data generated for that particular url too.
This way the site allowed me to log in and visit subdomains normally.
精彩评论