2017-02-10 100 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对象