2012-02-27 55 views
7

好吧,我一直在這個單獨的太空中喋喋不休。即使花費了數小時在這個網站和其他網站上,我也無法破解它。登錄會話不使用WebRequest/Response傳輸到新網頁?

本質上,我試圖使用WebRequest/Response從LogIn頁面後面的網頁剝離一些數據。 (我已經得到了這個工作使用WebBrowser控件的一些分層事件導航到不同的網頁,但它試圖重構時造成一些問題 - 更不用說已經指出,使用隱藏窗體來完成這項工作是' 。不好的做法」)

這是我有:

 string formParams = string.Format("j_username={0}&j_password={1}", userName, userPass); 
     string cookieHeader; 

     WebRequest request = WebRequest.Create(_signInPage); 
     request.ContentType = "text/plain"; 
     request.Method = "POST"; 
     byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
     request.ContentLength = bytes.Length; 
     using (Stream os = request.GetRequestStream()) 
     { 
      os.Write(bytes, 0, bytes.Length); 
     } 
     WebResponse response = request.GetResponse(); 
     cookieHeader = response.Headers["Set-Cookie"]; 

     WebRequest getRequest = WebRequest.Create(sessionHistoryPage); 
     getRequest.Method = "GET"; 
     getRequest.Headers.Add("Cookie", cookieHeader); 
     WebResponse getResponse = getRequest.GetResponse(); 
     try 
     { 
      using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
      { 
       textBox1.AppendText(sr.ReadToEnd()); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      throw; 
     } 

到目前爲止,我能夠從第一鏈接到正確的頁面,但是當我去到第二,它發送我回到登錄頁面,就好像我沒有登錄。

問題可能在於cookie沒有獲得c正確抓住,但我是新手,所以也許我只是做錯了。它捕獲從POST發回的cookie:JSESSIONID和S2V,但是當我們使用FireFox WebConsole進入「GET」時,瀏覽器顯示它發送了JSESSIONID,S2V SPRING_SECURITY_REMEMBER_ME_COOKIE,我相信這是使用的cookie當我點擊登錄表單上的「記住我」框。

我已經嘗試了許多不同的方式來使用SO的資源,但我還沒有到達需要的頁面。所以,爲了我已經離開的頭髮,我決定向好的SO尋求幫助。 (這是我不想放棄的東西之一 - 有時候會固執的那樣)

如果有人想要我登錄的網站的實際地址,我會更多而不願意通過私人信息將它發送給一對夫婦。

代碼,我要反映沃爾瑪建議答案:

var request = (HttpWebRequest)WebRequest.Create(sessionHistoryPage); 
request.Credentials = new NetworkCredential(userName, userPass); 
request.CookieContainer = new CookieContainer(); 
request.PreAuthenticate = true; 


WebResponse getResponse = request.GetResponse(); 
try 
{ 
    using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
    { 
      textBox1.AppendText(sr.ReadToEnd()); 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
    throw; 
} 

這個建議,至少我的方式來實現它,沒有奏效。

正如Krizz建議的那樣,我將代碼更改爲使用CookieContainer,並將cookie從一個請求傳輸到另一個請求,但響應只是讓我回到原始登錄頁面,就好像我沒有登錄一樣。

是否有某些網站不會允許此類行爲?

最終解決

最終的解決方案,提出了由阿德里安Iftode他說,我試圖登錄網站可能不允許有一個認證沒有一個有效的會話所以加入一個GET到該流程的開始允許我獲取該cookie。

感謝您的幫助!

+0

實用建議GET提琴手http://fiddler2.com,看看標題您登錄後準確發送和接收您的瀏覽器,然後模仿那些在你的C#代碼。 @zespri我以前使用的提琴手和,說實話,在我當前的編程能力水平 – 2012-02-28 00:51:33

+0

,這是在我的頭上。這是我正在處理的內容,但沒有多大幫助,我從FireFox Web控制檯獲得了相同的信息。 – Josh 2012-02-28 01:41:03

回答

5

我在做某種用PHP編寫的網站的cookie傳輸。 顯然要傳遞的餅乾,但也許就像是在這種情況下

var phpsessid = response.Headers["Set-Cookie"].Replace("; path=/", String.Empty); 

Set-Cookie頭包含有關該cookie和其他可能的指令其他餅乾等相關信息。我有一個cookie與它的信息(路徑),我需要發回服務器的會話ID,所以服務器會知道我是GET請求的同一個客戶端。

了新的要求必須包括這個cookie

request.Headers["Cookie"] = phpsessid; 

你已經做到這一點,但要確保您收到cookies,您發送回服務器。

考慮會話和認證,有兩個餅乾,一個會話,一個用於身份驗證和一些服務器/應用程序可能不允許有認證沒有一個有效的會話。我想說的是,你可能也需要傳遞會話cookie。所以步驟如下:

  • 首先執行GET請求以獲取會話cookie。
  • 下一步做POST請求進行認證,並獲得AUTH的cookie。
  • 使用兩種餅乾導航到受保護的頁面。

還要檢查this question,它並沒有顯示整個班級,但這個想法是保持的CookieContainer在同一個班,從POST添加新的cookie/GET請求,並將它們分配給每個新的請求,就像@Krizz回答。

+1

這是銀子彈。經過一些額外的測試後,我發現將第一個GET添加到代碼中是個訣竅。我甚至不需要切斷cookie中的「; path = /」。謝啦。 – Josh 2012-03-01 01:43:42

+1

18小時後我肯定會獎勵你賞金(網站不會讓我馬上去做)。 – Josh 2012-03-01 01:44:18

1

嘗試使用CookieContainer這是一個用於在多個請求之間保持Cookie上下文的類。您只需創建一個實例並將其分配給每個WebRequest

因此,修改代碼:

string formParams = string.Format("j_username={0}&j_password={1}", userName, userPass); 
string cookieHeader; 

var cookies = new CookieContainer(); // added this line 

var request = WebRequest.Create(_signInPage) as HttpWebRequest; // modified line 
request.CookieContainer = cookies; // added this line 
request.ContentType = "text/plain"; 
request.Method = "POST"; 
byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
request.ContentLength = bytes.Length; 
using (Stream os = request.GetRequestStream()) 
{ 
    os.Write(bytes, 0, bytes.Length); 
} 

request.GetResponse(); // removed some code here, no need to read response manually 

var getRequest = WebRequest.Create(sessionHistoryPage) as HttpWebRequest; //modified line 
getRequest.CookieContainer = cookies; // added this line 
getRequest.Method = "GET"; 
WebResponse getResponse = getRequest.GetResponse(); 
try 
{ 
    using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
    { 
     textBox1.AppendText(sr.ReadToEnd()); 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
    throw; 
} 
+0

我假設我需要改變,以HttpWebResponse /請求,因爲WebResponse類不具有的CookieContainer? – Josh 2012-02-29 21:17:48

+0

@Josh是的,你是對的,代碼固定 – Krizz 2012-02-29 22:22:18