好吧,我已经在这个独奏上绞尽脑汁待了太久。即使在这个和许多其他网站上花费了数小时,我也无法破解它。
基本上,我正在尝试使用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但我是新手所以也许我只是做错了。它捕获从POST发回的cookie:JSESSIONID和S2V然而,当我们使用FireFox WebConsole进入“GET”时,浏览器显示它发送了JSESSIONID,S2V 和一个SPRING_SECURITY_REMEMBER_ME_COOKIE,我相信是我点击登录表单上的“记住我”框时使用的cookie。
我尝试了很多不同的方法,使用SO的资源,但我还没有到达我需要的页面。因此,为了我留下的头发,我决定寻求有关好的SO的帮助。 (这是我不想放松的事情之一 - 有时像这样固执)
如果有人想要我正在尝试登录的网站的实际地址,我会非常乐意通过私信将其发送给几个人。
我必须反映Wal的建议答案的代码:
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从一个请求转移到另一个请求,但是响应只是让我回到原始登录页面,就好像我没有登录一样。
是否有某些网站不允许此类行为?
最终解决方案
最终的解决方案是由Adrian Iftode提出的,他说我尝试登录的网站可能不允许在没有有效会话的情况下进行身份验证,因此在开始时添加GET这个过程让我得到了那个cookie。
感谢你们的帮助!
答案 0 :(得分:6)
我正在为使用PHP编写的网站进行某种cookie转移。 很明显,你传递的是cookie,但也许就像那种情况一样
var phpsessid = response.Headers["Set-Cookie"].Replace("; path=/", String.Empty);
Set-Cookie
标头包含有关Cookie的其他相关信息以及其他Cookie的其他可能说明。我有一个带有信息(Path)的cookie,我需要将会话ID发送回服务器,这样服务器就会知道我是同一个发出GET请求的客户端。
新请求必须包含此Cookie
request.Headers["Cookie"] = phpsessid;
您已经这样做了,但请确保收到的cookies,然后发送回服务器。
考虑会话和身份验证,有两个cookie,一个用于会话,一个用于身份验证,一些服务器/应用程序可能不允许在没有有效会话的情况下进行身份验证。我想说的是你可能也需要传递会话cookie。所以步骤将是:
同时检查this question,它不显示整个类,但想法是将CookieContainer保持在同一个类中,从POST / GET请求添加新cookie并将它们分配给每个新请求,就像@Krizz一样回答。
答案 1 :(得分:2)
尝试使用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;
}