基本上,我试图使用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,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.
谢谢你们的帮助!
解决方法
很明显,你传递的是cookie,但也许就像那种情况一样
var PHPsessid = response.Headers["Set-Cookie"].Replace("; path=/",String.Empty);
Set-Cookie标头包含有关cookie的其他相关信息以及其他cookie的其他可能说明.我有一个cookie及其信息(路径),我需要发送回服务器的会话ID,所以服务器会知道我是做同一个GET请求的客户端.
新请求必须包含此cookie
request.Headers["Cookie"] = PHPsessid;
您已经这样做,但确保收到的cookie,您已发送回服务器.
考虑会话和身份验证,有两个cookie,一个用于会话,一个用于身份验证,一些服务器/应用程序可能不允许在没有有效会话的情况下进行身份验证.我想说的是你可能也需要传递会话cookie.所以步骤是:
>首先执行GET请求以获取会话cookie.
>接下来执行POST请求以进行身份验证并获取身份验证cookie.
>使用两个cookie导航到受保护的页面.
另外检查this question,它不显示整个类,但想法是将CookieContainer保持在同一个类中,从POST / GET请求添加新的cookie并将它们分配给每个新请求,如@Krizz回答.