如何使用PHP/cURL发布ASP.NET登录表单?

问题描述:

我需要创建一个工具,使用PHP发布ASP.NET登录表单,这样我就可以收集用户登录后显示的用户摘要页面的详细信息。如何使用PHP/cURL发布ASP.NET登录表单?

因为网站使用ASP.NET并且表单中有__VIEWSTATE和__EVENTVALIDATION隐藏字段,据我所知,我必须先获取这些值,然后将它们提交到登录表单中以使其工作。

我是PHP新手。我创建应做好以下脚本:

1)获取登录表单,并抢__VIEWSTATE和__EVENTVALIDATION

2)POST与适当的后数据的登录表单。

3)获取我现在应该可以访问的summary.htm页面,并对其进行身份验证。

实际发生的事情我不清楚。在发布到登录表单后,我收到一个cookie,但无法分辨该cookie是否表明我已通过身份验证。当我尝试获取summary.htm页面时,我被重定向回登录页面,就像我没有通过身份验证一样。

我是PHP的新手,我希望有人在那里熟悉它可能会看到明显的我失踪的东西。

下面是代码:

<?php 

require_once ("Includes/simple_html_dom.php"); 

ini_set('display_errors', 'On'); 
error_reporting(E_ALL); 

// Create curl connection 
$url = 'https://www.mysite.com/account/login.htm'; 
$cookieFile = 'cookie.txt'; 
$ch = curl_init(); 

// We must request the login page and get the ViewState and EventValidation hidden values 
// and pass those along in the post request. 

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setOpt($ch, CURLOPT_REFERER, 'https://www.mysite.com/account/login.htm'); 
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Origin: https://www.mysite.com', 'Host: www.mysite.com')); 


$curl_scraped_page = curl_exec($ch); 

// Grab ViewState and EventValidation data 
$html = str_get_html($curl_scraped_page); 
$viewState = $html->find("#__VIEWSTATE", 0); 
$eventValidation = $html->find("#__EVENTVALIDATION", 0); 
$previousPage = $html->find("#__PREVIOUSPAGE", 0); 


//create array of data to be posted 
// This matches exactly what I am seeing being posted when looking at Fiddler 
$post_data['__EVENTTARGET'] = ''; 
$post_data['__EVENTARGUMENT'] = ''; 
$post_data['__VIEWSTATE'] = $viewState->value; 
$post_data['__EVENTVALIDATION'] = $eventValidation->value; 
$post_data['__PREVIOUSPAGE'] = $previousPage->value; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$txtUsername'] = 'bsmith'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$txtPassword'] = 'Weez442'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$chkLoginPersist'] = 'on'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$btnLogin'] = 'Login >'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$LoginModal$LoginFields$txtModalUsername'] = ''; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$LoginModal$LoginFields$txtModalPassword'] = ''; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$SearchForm$inputText'] = ''; 

//traverse array and prepare data for posting (key1=value1) 
foreach ($post_data as $key => $value) { 
    $post_items[] = rawurlencode($key) . '=' . rawurlencode($value); 
} 

//create the final string to be posted using implode() 
$post_string = implode ('&', $post_items); 

//Set options for post 
curl_setOpt($ch, CURLOPT_POST, TRUE); 
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Origin: https://www.mysite.com', 'Host: www.mysite.com', 'Content-Type: application/x-www-form-urlencoded')); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); 
curl_setOpt($ch, CURLOPT_REFERER, 'https://www.mysite.com/account/login.htm'); 

// Perform our post request 
$curl_scraped_page = curl_exec($ch); 

echo $curl_scraped_page; 

// Now get our account summary page 
$urlAcctSummary = "https://www.mysite.com/my-account/summary.htm"; 
//Set options 
curl_setOpt($ch, CURLOPT_HTTPGET, TRUE); 
curl_setOpt($ch, CURLOPT_POST, FALSE); 
curl_setopt($ch, CURLOPT_URL, $urlAcctSummary); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); 

$curl_scraped_page = curl_exec($ch); 

echo $curl_scraped_page; 

curl_close($ch); 

?> 

我想通了。我以几种方式调整了代码,但我相信我的问题的根源在于ASP.NET想要从第一个GET请求中设置会话cookie,并且我只在POST请求中指定了CURLOPT_COOKIEJAR,并且在最终GET请求中仅指定了CURLOPT_COOKIEJAR 。

一旦我把CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE放在第一个GET请求中,它按照设计工作。

这里是我的代码是什么样子移动这些后:

<?php 

require_once ("Includes/simple_html_dom.php"); 

ini_set('display_errors', 'On'); 
error_reporting(E_ALL); 

// Create curl connection 
$url = 'https://www.mysite.com/account/login.htm'; 
$cookieFile = 'cookie.txt'; 
$ch = curl_init(); 

// We must request the login page and get the ViewState and EventValidation hidden values 
// and pass those along in the post request. 

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setOpt($ch, CURLOPT_REFERER, 'https://www.mysite.com/account/login.htm'); 
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Origin: https://www.mysite.com', 'Host: www.mysite.com')); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); 


$curl_scraped_page = curl_exec($ch); 

// Grab ViewState and EventValidation data 
$html = str_get_html($curl_scraped_page); 
$viewState = $html->find("#__VIEWSTATE", 0); 
$eventValidation = $html->find("#__EVENTVALIDATION", 0); 
$previousPage = $html->find("#__PREVIOUSPAGE", 0); 


//create array of data to be posted 
// This matches exactly what I am seeing being posted when looking at Fiddler 
$post_data['__EVENTTARGET'] = ''; 
$post_data['__EVENTARGUMENT'] = ''; 
$post_data['__VIEWSTATE'] = $viewState->value; 
$post_data['__EVENTVALIDATION'] = $eventValidation->value; 
$post_data['__PREVIOUSPAGE'] = $previousPage->value; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$txtUsername'] = 'bsmith'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$txtPassword'] = 'Weez442'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$LoginFields$chkLoginPersist'] = 'on'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateContent$MyAccountLogin967$btnLogin'] = 'Login >'; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$LoginModal$LoginFields$txtModalUsername'] = ''; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$LoginModal$LoginFields$txtModalPassword'] = ''; 
$post_data['ctl00$ctl00$cphMasterBody$cphPageTemplateTopHeader$IncludeHeader$SearchForm$inputText'] = ''; 

//traverse array and prepare data for posting (key1=value1) 
foreach ($post_data as $key => $value) { 
    $post_items[] = rawurlencode($key) . '=' . rawurlencode($value); 
} 

//create the final string to be posted using implode() 
$post_string = implode ('&', $post_items); 

//Set options for post 
curl_setOpt($ch, CURLOPT_POST, TRUE); 
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Origin: https://www.mysite.com', 'Host: www.mysite.com', 'Content-Type: application/x-www-form-urlencoded')); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setOpt($ch, CURLOPT_REFERER, 'https://www.mysite.com/account/login.htm'); 

// Perform our post request 
$curl_scraped_page = curl_exec($ch); 

echo $curl_scraped_page; 

// Now get our account summary page 
$urlAcctSummary = "https://www.mysite.com/my-account/summary.htm"; 
//Set options 
curl_setOpt($ch, CURLOPT_HTTPGET, TRUE); 
curl_setOpt($ch, CURLOPT_POST, FALSE); 
curl_setopt($ch, CURLOPT_URL, $urlAcctSummary); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 

$curl_scraped_page = curl_exec($ch); 

echo $curl_scraped_page; 

curl_close($ch); 

?> 
+0

你好,你的代码的伟大工程,但我需要有dopostback页作为总结网址,我尝试的选项很多,但没有运气,当登录后我想发邮件一切都出错了。 $ post_data ['__ EVENTTARGET'] ='grdInbox'; $ post_data ['__ EVENTARGUMENT'] ='页面%241'; 您是否有任何关于dopostback分页数据的经验,登录后应该怎么做?如果你帮我,我会非常开心。 谢谢! – 2016-03-06 20:03:12