如何为返回的 Set-Cookie 会话 ID 解析 HttpWebResponse.Headers.Keys

Posted

技术标签:

【中文标题】如何为返回的 Set-Cookie 会话 ID 解析 HttpWebResponse.Headers.Keys【英文标题】:How to parse HttpWebResponse.Headers.Keys for a Set-Cookie session id returned 【发布时间】:2010-11-06 13:14:18 【问题描述】:

我正在尝试创建与 ASP.NET 网站的 HttpWebRequest/HttpWebResponse 会话,以便稍后通过 url 参数解析 html 表单(这部分我知道该怎么做),但我不明白如何解析和设置cookie,例如会话 ID。在Fiddler中,它显示ASP.NET Session ID是通过Set-Cookie在对url的/路径的请求的响应中返回的,但是我怎样才能提取这个session id并将其设置为下一个HttpWebRequest的cookie ?我知道这个 Set-Cookie 标头可以在 HttpWebResponse.Headers.Keys 中找到,但是有解析它的直接路径吗?谢谢!

【问题讨论】:

【参考方案1】:

.NET 框架将为您管理 cookie。您不必担心从标头中解析 cookie 信息或将 cookie 标头添加到您的请求中。

要存储和发送您的会话 ID,请使用 CookieCookieContainer 类来存储它们,然后确保随每个请求发送您的 cookie。

以下示例显示了如何执行此操作。 CookieContainer 'cookieJar' 可以在多个域和请求之间共享。将它添加到请求对象后,在返回响应时,对它的引用也会添加到响应对象中。

CookieContainer cookieJar = new CookieContainer();

var request = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com");
request.CookieContainer = cookieJar;

var response = request.GetResponse();

foreach (Cookie c in cookieJar.GetCookies(request.RequestUri))

    Console.WriteLine("Cookie['" + c.Name + "']: " + c.Value);

这段代码的输出将是:

Cookie['PREF']: ID=59e9a22a8cac2435:TM=1246226400:LM=1246226400:S=tvWTnbBhK4N7Tlpu

【讨论】:

+1 感谢您的帮助!我并不期待手动解析 HTTP 标头 :) 这是一个意外的行为... response.Cookies 不应该在 CookieContainer 未定义时为空。 @DaviFiamenghi 然而,这是记录在案的行为。 Microsoft 希望您拥有一个 cookie 管理对象以在 Web 请求/响应之间共享。如果不这样做,则需要手动解析响应的 cookie 标头。 @DanHerbert 太好了。但我仍然认为,如果在未定义容器的情况下尝试访问响应的“Cookies”属性时抛出 InvalidOperationException 会更直观。当我看到 0 个 cookie 时,我以为响应中有 0 个 cookie。这种行为就像您尝试读取已处置的流或类似的东西......而且我相信如果引发解释性异常,它将阻止人们询问 SO 或滚动您自己的 cookie 解析逻辑。 【参考方案2】:

Dan Herbert 的回答对我很有帮助。感谢您的帮助。

只是想发布我的用法-希望它在某个时间点对某些人有所帮助。我的要求是我需要将 cookie 从第一个 http post 响应发送回第二个 http post 请求。

第一个:

CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
....

CookieCollection setCookies = cookieJar.GetCookies(request.RequestUri);

第二个:

CookieContainer cc = new CookieContainer();
cc.Add(setCookies);    
request.CookieContainer = cc;

【讨论】:

【参考方案3】:

我有同样的问题(亚马逊) 我使用以下正则表达式:

string regexp = "(?[^=]+)=(?[^;]+)[^,]+,?";);MatchCollection myMatchCollection = Regex.Matches (cookiesStr, regexp);foreach (匹配 myMatchCollection 中的 myMatch)  string cookieName = myMatch.Groups["name"].ToString(); string cookieVal = myMatch.Groups[" val"].ToString(); Cookie cookie = new Cookie(cookieName, cookieVal); cookies.Add(cookie);  

请注意,我只关心 cookie 名称/值...

祝你好运 埃利亚

【讨论】:

这正是我正在寻找的解决方案类型(WebBrowser 对象仅提供 cookie 的字符串)。但是,您的代码无法编译。【参考方案4】:

嗯,我可能错了,但从我最近的观察来看

来自第一个响应的 Cookie,在 302(重定向)状态的情况下,不要将“设置 cookie”作为 cookie 包含在标头中(例如某些会话 id...)

如果 autofollowredirect 设置为 true,则处理设置的 cookie,并且自动完成的后续请求将包括在第一次调用时由 set cookie 定义的那些 cookie

如果 autofollowredirect 设置为 false,那么第一个请求不会获得由设置的 cookie 定位的 cookie,我猜这也是我的问题,如果有人知道的话,这是随后在下一个请求中拥有这些 cookie 的唯一方法,是解析设置的cookies吗?

【讨论】:

我遇到了 302 重定向问题,并设置了 AllowAutoRedirect = false。这给了我一个“此页面已移动”的响应,但随后我将 cookie 传递并重定向到我想首先访问的页面。 According to RFC 6265 用户代理可以忽略包含在具有 100 级状态代码的响应中的 Set-Cookie 标头,但必须处理包含在其他响应中的 Set-Cookie 标头(包括具有 400 级和 500 级状态的响应代码)。

以上是关于如何为返回的 Set-Cookie 会话 ID 解析 HttpWebResponse.Headers.Keys的主要内容,如果未能解决你的问题,请参考以下文章

如何为cookie设置HttpOnly

接受 id 并返回表的函数 - 如何为多个 id 调用它?

如何为丢失的资源建模权限?

如何为登录GRAILS(Spring security)的用户实现会话?

如何为所有会话创建配置单元 UDF

如何为Laravel中的每个会话设置不同的到期时间?