2017-02-10 47 views
0

我試圖寫一個腳本在C#能夠從網站檢索一些信息。這些信息是受保護的,所以我需要登錄才能閱讀它們。這就是我認爲應該是我的程序:登錄到需要使用c#的Cookie的網站#

我已經使用Firefox或Chrome的某些工具測試了標頭,但我無法理解哪個是正確的過程。我注意到,如果我打開這個登錄頁面,我會收到一些cookie。如果我刪除這些cookie並嘗試通過插入用戶名和密碼(通過瀏覽器)登錄,我收到一個錯誤,作爲網站的迴應..它說我需要激活cookie才能夠登錄。因此,當我第一次打開登錄頁面時,似乎收到一些cookie,然後我需要將它們與第一次POST請求登錄在一起。這對你們中的任何人都有意義嗎?

這就是我現在使用的代碼:

 string formUrl = "https://idp.kk-abcdefg.de/idp/Authn/UserPassword"; 
     string formParams = string.Format("j_username=MyUserName&j_password=MyPassword」); 
     string cookieHeader; 
     string pageSource; 
     WebRequest req = WebRequest.Create(formUrl); 
     req.ContentType = "application/x-www-form-urlencoded"; 
     req.Method = "POST"; 
     byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
     req.ContentLength = bytes.Length; 
     using (Stream os = req.GetRequestStream()) 
     { 
      os.Write(bytes, 0, bytes.Length); 
     } 
     WebResponse resp = req.GetResponse(); 
     cookieHeader = resp.Headers["Set-cookie"]; 

     using (StreamReader sr = new StreamReader(resp.GetResponseStream())) 
     { 
      pageSource = sr.ReadToEnd(); 
     } 

,我相信這是工作,因爲如果我使用正確的用戶名/密碼pageSource的結果改變或者我寫他們錯了。但是當用戶/密碼正確時,我仍然無法登錄,因爲我收到以下錯誤消息:「此應用程序需要cookie,請確保在瀏覽器設置中啓用了Cookie,請重新加載登錄頁面並嘗試再次登錄「。

這與我在瀏覽器中禁用Cookie時獲得的錯誤相同,或者我刪除了第一次加載登錄頁面時得到的cookie。

你能幫助我嗎?我的想法是,我需要保存第一次打開登錄頁面時收到的Cookie,然後將它們與以下請求一起發送,但我不知道該怎麼辦..

非常感謝!

+0

您是否嘗試過使用Fiddler查看登錄後在請求上設置了哪些Cookie?這樣你可以複製相同的行爲。我看到你正在得到餅乾,但可能不會在任何地方設置它們。 – bc004346

回答

0

在Web應用程序中,一旦用戶成功登錄,cookie將被髮送回瀏覽器以跟蹤用戶會話並確定用戶是否在進一步請求期間登錄。此外,您的應用程序的登錄過程需要從客戶端發送cookie以及用戶名和密碼。所以當你試圖在沒有瀏覽器的情況下執行登錄時,它會抱怨缺少cookie。

如果您知道cookie和它們的值需要與登錄用戶名和密碼一起發送,您可以使用WebRequest中的cookieContainer發送它們,如下所示。

string formUrl = "https://idp.kk-abcdefg.de/idp/Authn/UserPassword"; 
string formParams = string.Format("j_username=MyUserName&j_password=MyPassword"); 

string cookieHeader; 
string pageSource; 

CookieContainer cookieContainer = new CookieContainer(); 
Cookie cookie1 = new Cookie("<<cookiename>>", "<<cookievalue>>","/", "<<yourdomainname>>"); 
Cookie cookie2 = new Cookie("<<cookiename>>", "<<cookievalue>>", "/", "<<yourdomainname>>"); 
cookieContainer.Add(cookie1); 
cookieContainer.Add(cookie2); 

// You can keep adding all required cookies this way. 
var req = (HttpWebRequest)WebRequest.Create(formUrl); 
req.CookieContainer = cookieContainer; 

req.ContentType = "application/x-www-form-urlencoded"; 
req.Method = "POST"; 
byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
req.ContentLength = bytes.Length; 
using (Stream os = req.GetRequestStream()) 
{ 
    os.Write(bytes, 0, bytes.Length); 
} 
WebResponse resp = req.GetResponse(); 
cookieHeader = resp.Headers["Set-cookie"]; 

// You can access the cookies coming as part of response as following. 
HttpWebResponse response = resp as HttpWebResponse; 
if(response != null) 
{ 
    var cookiesCollections = response.Cookies; 
} 

using (StreamReader sr = new StreamReader(resp.GetResponseStream())) 
{ 
    pageSource = sr.ReadToEnd(); 
} 

如果你不知道的cookie,你需要通過發佈用戶名和密碼,然後用下面的請求之前登錄頁面先拿到餅乾。

var loginPageUrl = "<<Your Login Page url>>"; 
CookieContainer cookieContainer = new CookieContainer(); 
var req = (HttpWebRequest)WebRequest.Create(loginPageUrl); 
req.CookieContainer = cookieContainer; 
req.Method = "GET"; 

WebResponse resp = req.GetResponse(); 

HttpWebResponse response = resp as HttpWebResponse; 

CookieCollection cookies; 
if (response != null) 
{ 
    cookies = response.Cookies; //Use this cookies in above code to send with username and password. 
} 
+0

Chetan,非常感謝!你的解釋澄清了我很多事情。不幸的是它仍然無法正常工作。我嘗試了第二種方法:我首先使用GET來訪問登錄頁面並獲取cookie。然後,我使用POST與用戶/傳遞和CookieContainer.add(餅乾),其中Cookie =來自GET的response.Cookies。問題是現在我的「cookieHeader = resp.Headers [」Set-cookie「];」是空的,所以我什麼都沒有回來..你有什麼建議嗎?非常感謝! – Emanuele

+0

您不需要爲cookie使用響應標頭。使用與您用來從get調用中檢索cookie相同的方法。 –

+0

即使使用與GET相同的方法,我在POST後也不會收到任何回覆。通過使用firefox進行檢查,我注意到在登錄之前我有2個不同的cookie,登錄後有2個不同的cookie(共4個) 。這兩個是_pk_ref和_pk_ses類型,所以它們是Piwik餅乾。你認爲這可能是我無法登錄的原因嗎?謝謝! – Emanuele

0

你發送請求登錄兩次,使用單一的CookieContainer對象