【问题标题】:How to get response cookies using System.Net.Http.HttpClient?如何使用 System.Net.Http.HttpClient 获取响应 cookie?
【发布时间】:2018-08-10 20:56:53
【问题描述】:

这个问题已经被问过好几次了,但我找不到一个明确的答案。是否甚至可以使用 System.Net.Http.HttpClient 获取响应 cookie?

【问题讨论】:

  • 您是否按照这个问题stackoverflow.com/questions/17983992/… 的描述查看过CookieContainer?
  • 是的,我有,还有其他一些帖子。它们都没有显示如何从响应中获取 cookie。

标签: dotnet-httpclient


【解决方案1】:

以下是我用于访问服务器生成的 cookie 的一些示例代码。我刚刚测试了它,它对我有用。我更改了凭据。如果您想看到它正常工作,您需要为自己创建一个 nerddinner 帐户。

    [Fact]
    public async Task Accessing_resource_secured_by_cookie()
    {
        var handler = new HttpClientHandler();
        var httpClient = new HttpClient(handler);

        Assert.Equal(0, handler.CookieContainer.Count);

        // Create a login form
        var body = new Dictionary<string, string>() 
        {
            {"UserName",  "<username>"},
            {"Password", "<password>"},
            {"RememberMe", "false"}
        };
        var content = new FormUrlEncodedContent(body);

        // POST to login form
        var response = await httpClient.PostAsync("http://www.nerddinner.com/Account/LogOn?returnUrl=%2F", content);

        // Check the cookies created by server
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.Equal(1, handler.CookieContainer.Count);
        var cookies = handler.CookieContainer.GetCookies(new Uri("http://www.nerddinner.com"));
        Assert.Equal(".ASPXAUTH", cookies[0].Name);

        // Make new request to secured resource
        var myresponse = await httpClient.GetAsync("http://www.nerddinner.com/Dinners/My");

        var stringContent = await myresponse.Content.ReadAsStringAsync();
        Assert.Equal(HttpStatusCode.OK, myresponse.StatusCode);
    }

从代码中可以看出,您不会直接从 HTTP 响应消息中获取响应 cookie。我怀疑 HttpClientHandler 在返回之前将响应头从响应中剥离。但是,响应中的 cookie 被放置在 CookieContainer 中,您可以从那里访问它们。

【讨论】:

  • 对我不起作用。使用 HttpWebRequest 发出的相同请求返回三个 cookie,而 HttpClient 仅返回 1。可能与 cookie 类型有关吗? HttpClient 不返回的 cookie 是由 FederatedAuthentication ASP.NET MVC 模块产生的 FedAuth 和 FetAuth1 cookie。
  • @AlexI 当您说“HttpClient 仅返回 1”时,您的意思是 HttpResponseMessage Headers 中只有 1 个 cookie,还是 CookieContainer 仅包含 1 个?如果你的意思是后者,那么我很困惑,因为在幕后,HttpClient 使用与 HttpWebRequest/HttpWebResponse 完全相同的代码。
【解决方案2】:

要获取响应cookie,您可以使用此方法;

private async Task<string> GetCookieValue(string url, string cookieName)
{
    var cookieContainer = new CookieContainer();
    var uri = new Uri(url);
    using (var httpClientHandler = new HttpClientHandler
    {
        CookieContainer = cookieContainer
    })
    {
        using (var httpClient = new HttpClient(httpClientHandler))
        {
            await httpClient.GetAsync(uri);
            var cookie = cookieContainer.GetCookies(uri).Cast<Cookie>().FirstOrDefault(x => x.Name == cookieName);
            return cookie?.Value;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2020-10-28
    • 2012-10-02
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    相关资源
    最近更新 更多