.net 4.5에서 HttpClient를 사용하여 쿠키를 응답에서 벗어나려는 시도


107

성공적으로 작동하는 다음 코드가 있습니다. 응답에서 쿠키를 가져 오는 방법을 알 수 없습니다. 내 목표는 요청에 쿠키를 설정하고 응답에서 쿠키를 가져올 수 있기를 원합니다. 생각?

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();
    }
}

완전한 대답은 다음과 같습니다.

HttpResponseMessage response = await client.PostAsync(url,content);
response.EnsureSuccessStatusCode();

Uri uri = new Uri(UrlBase);
var responseCookies = cookieJar.GetCookies(uri);
foreach (Cookie cookie in responseCookies)
{
    string cookieName = cookie.Name;
    string cookieValue = cookie.Value;
}

궁금해서 클라이언트에서 쿠키를 읽으려는 이유를 물어봐도 될까요? 내 이해는 쿠키가 정보를 반환하는 것이 아니라 서버에 정보를 보내는 데 사용된다는 것입니다.
Darrel Miller 2012

JSON을 반환하는 호출에 대해 반환 된 쿠키를 사용하므로 각 JSON 호출에 대해 별도의 인증 호출을 수행 할 필요가 없습니다. 즉, JSON을 반환하지만 권한이있는 경우에만 호출 로그 / Home / GetData가 있습니다. 클라이언트 요청에서 / Home / GetData가 응답하도록 쿠키를 추가합니다. 그렇지 않으면 "403"무단으로 표시됩니다.
Peter Kellner

인증 헤더를 기본 헤더로 설정하는 것은 거의 효과적이고 좀 더 표준 적입니다. 서버가 클라이언트를 대신하여 자동으로 인증 헤더를 설정할 수있는 방법은 없습니다.
Darrel Miller

1
팁 Darrel에 감사드립니다. asp.net에서 어떻게 보일지에 대한 예가 있습니까? 나는 monotouch와 이제 내 Windows 스토어 앱을 위해 이것을 고생했습니다. 간단한 방법이 있다면 기쁠 것입니다. 이것은 특히 async의 경우 고통이며 Windows 스토어 앱에서 지금 기다리고 있습니다.
Peter Kellner

답변:


170

요청에 쿠키를 추가하려면 요청 전에 쿠키 컨테이너를 CookieContainer.Add(uri, 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();

8
참고 : 첫 번째 호출에서 초기 쿠키를 수신 한 후 동일한 도메인의 페이지에 액세스하면 쿠키가 자동으로 전송되며 추가 단계가 필요하지 않습니다.
Jahmic

"using System.linq;"를 추가해야합니다.
Cabuxa.Mapache

^^ System.Linq는 .Cast <> 메서드를 사용하려는 경우에만 필요하며 쿠키 검색에는 필요하지 않지만 자명해야합니다. :)
MikeDub

httpclienthttpclient 팩토리에서 빌드 된 경우 동일한 방법으로 쿠키를 가져올 수 있습니까? 즉 빌더 방법은 services.AddHttpClient에 추가
user3279954

Get Async에서 우리는 이미 "google.com"에 대한 참조를 만들었습니다. 왜 다시 참조를 포함하는 URI를 선언해야합니까?
Malcolm Salvador

7

당신은에 액세스 할 수없는 경우 다른있다 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;
}

1
훌륭하고 날 것이지만 내가 필요한 건 ... 잘 했어, 고마워.
Vedran Mandić

5

주어진 URL로 쿠키 값을 쉽게 얻을 수 있습니다.

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;
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.