2011-02-07 77 views
1

我試圖根據我看到的來自Firefox中的Live HTTP頭文件來模擬POST到網站。用PHP和cURL模擬一個POST

這裏的日誌從Firefox插件的複製/粘貼:

POST /上下文選項卡=登錄HTTP/1.1
主持人:網站
的User-Agent: 的Mozilla/5.0(X11; U; Linux i686; en-US; rv:1.9.2.13)Gecko/20101206 Ubuntu/10.10(maverick) Firefox/3.6.13
接受: text/html,application/xhtml + xml,application/xml; q = 0.9,/; q = 0.8
Accept-Language:en-us,en; Q = 0.5
接受編碼:gzip,放氣
接收字符集: ISO-8859-1,utf-8; Q = 0.7,*; Q = 0.7
保持活動:115
連接: 保-alive
引用者:引用者
Cookie:fontsize = 2; JSESSIONID = 0000pXE_BK7TjZFzEyNHqOKzXz2:-1
內容類型: 應用/ X WWW的窗體-urlencoded
的Content-Length:46
登錄ID =密碼&密碼=密碼&登錄名=登錄

以及POST後立即響應:

HTTP/1.1 302 Found found
Location: website/context?ta b = p00689
內容 - 語言:en-US
Set-Cookie: JSESSIONID = 0000oaKlIeeDRWkX5YCiJu5v1lM:-1; 路徑=/
傳輸編碼:分塊 日期
:星期一,2011年2月7日14時15分21秒 GMT
服務器:的WebSphere 應用服務器/ 6.1
截止日期: 星期四,1994 16:00:00 GMT 12月01日
緩存控制:無緩存= 「設置Cookie, 設置COOKIE2」

根據我的測試,一個重定向到

網站/上下文響應標籤= p 00689

表示用戶已通過身份驗證並且一切正常。

但是,當試圖通過PHP & cURL完成此操作時,我被重定向到通知用戶其會話已超時的頁面。

下面的代碼:

// Provider only likes Firefox 
$agent = "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"; 

ini_set("user_agent", $agent); 

// Cookie 
$cookie = tempnam("/tmp", "curlcookie"); 

// Post everything that was posted to me. 
$fields = $_POST; 

foreach($fields as $key=>$value) 
{ 
     $fields_string .= "$key=$value&"; 
} 

$fields_string = substr($fields_string, 0, strlen($fields_string) - 1); 

// Custom headers 
$headers = array(
     "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
     "Accept-Language: en-us,en;q=0.5", 
     "Accept-Encoding: gzip,deflate", 
     "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7", 
     "Keep-Alive: 115", 
     "Connection: keep-alive"); 

// cURL options 
$ch = curl_init("website"); 

curl_setopt($ch, CURLOPT_REFERER, "referer"); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 
curl_setopt($ch, CURLOPT_MAXREDIRS, 1); 
curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 

$output = curl_exec($ch); 
$header = curl_getinfo($ch); 

curl_close($ch); 

// Debugging junk 
echo nl2br($header["request_header"]); 
echo "<br/><br/>Output:<br/><br/>$output"; 

從腳本的輸出如下所示:

POST /上下文選項卡=登錄HTTP/1.1
的User-Agent:用戶代理: Mozilla的/ 5.0 (X11; U; Linux的i686的; EN-US; RV:1.9.2.13)的Gecko/20101206 的Ubuntu/10.10(特立獨行) 的Firefox/3.6.13
主持人:網站
雜注:無緩存
的Referer: 引用者
接受: text/html的,是application/xhtml + xml的,應用/ XML; Q = 0.9,/; Q = 0.8
接受語言:EN-US,烯; q = 0.5
接受編碼:gzip,放氣
接收字符集: ISO-8859-1,utf-8; q = 0.7,*; q = 0.7
保持活動:115
連接: keep-alive
Content-Length: Content-Type: application/x-www-form-urlencoded

登錄ID =用戶名&密碼=密碼&登錄=登錄


輸出:

HTTP/1.1 302
找到
位置:網站/上下文選項卡= p00697
內容語言:zh-CN Set-Cookie:
JSESSIONID = 0000Tl8NL1Hg2dbNv_PEnq-bbvr:-1;
Path =/Set-Cookie:
JSESSIONID = 0000Zue58y1tXg3tt4XjB8exXw6:-1;
路徑= /傳輸編碼:分塊
日期:星期一,2011年2月7日19時18分二十〇秒GMT
服務器:在WebSphere Application
服務器/ 6.1到期日:星期四,1994年
16:00:00 12月01日格林尼治標準時間的Cache-Control:
無緩存= 「設置cookie的,
設置COOKIE2」

基於我已經發布,有什麼明顯的是我失蹤?接下來我應該嘗試什麼?請求在語義上看起來是一樣的;我不確定我可能做錯了什麼。

+1

怎麼樣從原來的POST的Cookie頭? – 2011-02-07 19:59:26

+1

完成發佈所需的cookie不是服務器1,而是目標服務器的cookie,因爲cookie將在登錄點創建。我相信, – RobertPitt 2011-02-07 20:03:43

回答

1

的一兩件事,突出的是下面的代碼行:

$cookie = tempnam("/tmp", "curlcookie"); 

現在,如果這無法創建文件,然後tempnam將返回false,這意味着下面的代碼行:

curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); 

與完全沒有設置好一樣好,您應該將cookie文件保存在與執行腳本相同的目錄中。

接下來的事情就是:

$fields = $_POST; 
foreach($fields as $key=>$value) 
{ 
    $fields_string .= "$key=$value&"; 
} 
$fields_string = substr($fields_string, 0, strlen($fields_string) - 1); 

您不必這樣做,因爲CURLOPT_POSTFIELDS接受一個數組,所以你應該能夠做到:

curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST); 

這將確保實體被正確解析。

我還以爲你可以刪除ini_set因爲這是本機的功能,如file_get_contentsfopen流等,所以仔細檢查線路:

ini_set("user_agent", $agent); 

而且我會檢查,看看是否有一個cookie已經從主頁面設置,如index.php,因爲該網站可能會阻止來自直接來到包含數據的登錄頁面的請求。