繁体   English   中英

在 .net 4.5 中尝试使用 HttpClient 使 cookie 脱离响应

[英]Struggling trying to get cookie out of response with HttpClient in .net 4.5

我有以下成功运行的代码。我不知道如何从响应中获取 cookie。我的目标是我希望能够在请求中设置 cookie 并从响应中获取 cookie。想法?

private async Task<string> Login(string username, string password)
{
    try
    {
        string url = "http://app.agelessemail.com/account/login/";
        Uri address = new Uri(url);
        var postData = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("username", username),
            new KeyValuePair<string, string>("password ", password)
        };

        HttpContent content = new FormUrlEncodedContent(postData);
        var cookieJar = new CookieContainer();
        var handler = new HttpClientHandler
        {
            CookieContainer = cookieJar,
            UseCookies = true,
            UseDefaultCredentials = false
        };

        var client = new HttpClient(handler)
        {
            BaseAddress = address
        };


        HttpResponseMessage response = await client.PostAsync(url,content);
        response.EnsureSuccessStatusCode();
        string body = await response.Content.ReadAsStringAsync();
        return body;
    }
    catch (Exception e)
    {
        return e.ToString();
    }
}

要将 cookie 添加到请求中,请在请求之前使用CookieContainer.Add(uri, cookie)填充 cookie 容器。 发出请求后,cookie 容器将自动填充响应中的所有 cookie。 然后您可以调用 GetCookies() 来检索它们。

CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;

HttpClient client = new HttpClient(handler);
HttpResponseMessage response = client.GetAsync("http://google.com").Result;

Uri uri = new Uri("http://google.com");
IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
    Console.WriteLine(cookie.Name + ": " + cookie.Value);

Console.ReadLine();

如果您无权访问HttpClient并且无法注入CookieContainer ,则还有另一种选择。 这适用于 .NET Core 2.2:

private string GetCookie(HttpResponseMessage message)
{
    message.Headers.TryGetValues("Set-Cookie", out var setCookie);
    var setCookieString = setCookie.Single();
    var cookieTokens = setCookieString.Split(';');
    var firstCookie = cookieTokens.FirstOrDefault();
    var keyValueTokens = firstCookie.Split('=');
    var valueString = keyValueTokens[1];
    var cookieValue = HttpUtility.UrlDecode(valueString);
    return cookieValue;
}

您可以使用给定的 URL 轻松获取 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;
        }
    }
}

并非在所有情况下都可以将httpClientHandler添加到httpClient 例如,当您使用集成测试的testServer.CreateClient()或从IHttpClientFactory注入httpClient时。 所以,我只是从标题中读取值。

    public static List<Cookie> GetCookies(this HttpResponseMessage message)
    {
        message.Headers.TryGetValues("Set-Cookie", out var cookiesHeader);
        var cookies = cookiesHeader.Select(cookieString => CreateCookie(cookieString)).ToList();
        return cookies;
    }

    private static Cookie CreateCookie(string cookieString)
    {
        var properties = cookieString.Split(';', StringSplitOptions.TrimEntries);
        var name = properties[0].Split("=")[0];
        var value = properties[0].Split("=")[1];
        var path = properties[2].Replace("path=", "");
        var cookie = new Cookie(name, value, path)
        {
            Secure = properties.Contains("secure"),
            HttpOnly = properties.Contains("httponly"),
            Expires = DateTime.Parse(properties[1].Replace("expires=", ""))
        };
        return cookie;
    }

可以修改CreateCookie方法以完全匹配您的 cookie 属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM