HttpClient의 HttpRequestMessage에서 쿠키를 설정하는 방법


247

웹 API를 사용하여 HttpClient계정을 식별하는 HTTP 쿠키 형식으로 로그인 해야하는 끝점에 게시하려고합니다 (이것은 #ifdef릴리스 버전에서 나온 것입니다).

에 쿠키를 어떻게 추가 HttpRequestMessage합니까?

답변:


374

요청에 대한 맞춤 쿠키 값을 설정하는 방법은 다음과 같습니다.

var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("foo", "bar"),
        new KeyValuePair<string, string>("baz", "bazinga"),
    });
    cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
    var result = await client.PostAsync("/test", content);
    result.EnsureSuccessStatusCode();
}

2
처리기는 using 문에서 제거 될 수 있으며 http 클라이언트가 삭제되면 처리됩니다.
Kimi

17
Kimi는 정확하지만 사용 중에 HttpClient를 래핑해서는 안됩니다. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Robert McLaws

9
주의 : 하나의 HttpClient 인스턴스 만 사용하여 여러 요청을 수행하면 CookieContainer를 사용하는 쿠키가 캐시됩니다. 사용자가 다른 사용자로부터 쿠키를 얻는 것은 위험합니다.
Acaz Souza

31
"HttpClient는 한 번 인스턴스화되어 응용 프로그램 수명 동안 재사용됩니다. 특히 서버 응용 프로그램에서 모든 요청에 ​​대해 새 HttpClient 인스턴스를 만들면로드가 많을 때 사용 가능한 소켓 수가 소진됩니다 ..."여기에서 : asp .net / web-api / overview / advanced /…
SergeyT

4
@ SergeyT 그래서 같은 리소스에 대해 별도의 세션 호출을해야 할 때 무엇을합니까? :)
AgentFire

337

허용 대답은 대부분의 경우이 작업을 수행하는 올바른 방법입니다. 그러나 쿠키 헤더를 수동으로 설정하려는 상황이 있습니다. 일반적으로 "쿠키"헤더를 설정하면 헤더가 무시되지만 HttpClientHandler기본적으로 CookieContainer쿠키 의 속성 을 사용 하기 때문 입니다. 이를 비활성화하면로 설정 UseCookies하여 false쿠키 헤더를 수동으로 설정할 수 있으며 요청에 쿠키 헤더가 표시됩니다.

var baseAddress = new Uri("http://example.com");
using (var handler = new HttpClientHandler { UseCookies = false })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var message = new HttpRequestMessage(HttpMethod.Get, "/test");
    message.Headers.Add("Cookie", "cookie1=value1; cookie2=value2");
    var result = await client.SendAsync(message);
    result.EnsureSuccessStatusCode();
}

44
SendAsync로 보낸 요청이 쿠키 헤더를 보내지 않는 오류를 며칠 동안 추적했습니다. 이것은 처리기에서 UseCookies = false를 설정하지 않으면 CookieContainer를 사용할뿐만 아니라 요청 헤더에 저장된 쿠키를 자동으로 무시 한다는 것을 깨달았습니다 . 정말 고맙습니다!
Fernando Neira

14
이 답변은 HttpClient를 프록시로 사용하려는 모든 사람에게 매우 유용합니다!
cchamberlain

3
지금 시도해 보면 ... 효과가 있다면 ... 캐나다 포옹이 꼭 필요합니다.
Maxime Rouiller

11
주의 : 하나의 HttpClient 인스턴스 만 사용하여 여러 요청을 수행하면 CookieContainer를 사용하는 쿠키가 캐시됩니다. 사용자가 다른 사용자로부터 쿠키를 얻는 것은 위험합니다.
Acaz Souza

9
누군가가 "쿠키"헤더를 조용히 잃어 버리지 않고 추가하려고 할 때 그 멍청한 일은 예외를 던져야합니다. 한 시간 내 인생의 비용이 들었습니다. 솔루션 주셔서 감사합니다.
stmax

5

이 문제에 대해 몇 시간을 보낸 후 위의 답변 중 어느 것도 도움이되지 않아서 정말 유용한 도구를 찾았습니다.

먼저 Telerik의 Fiddler 4를 사용하여 웹 요청을 자세히 연구했습니다.

두 번째로, 나는 Fiddler를위한이 유용한 플러그인을 발견했습니다 :

https://github.com/sunilpottumuttu/FiddlerGenerateHttpClientCode

C # 코드를 생성합니다. 예를 들면 다음과 같습니다.

        var uriBuilder = new UriBuilder("test.php", "test");
        var httpClient = new HttpClient();


        var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uriBuilder.ToString());



        httpRequestMessage.Headers.Add("Host", "test.com");
        httpRequestMessage.Headers.Add("Connection", "keep-alive");
     //   httpRequestMessage.Headers.Add("Content-Length", "138");
        httpRequestMessage.Headers.Add("Pragma", "no-cache");
        httpRequestMessage.Headers.Add("Cache-Control", "no-cache");
        httpRequestMessage.Headers.Add("Origin", "test.com");
        httpRequestMessage.Headers.Add("Upgrade-Insecure-Requests", "1");
    //    httpRequestMessage.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        httpRequestMessage.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
        httpRequestMessage.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        httpRequestMessage.Headers.Add("Referer", "http://www.translationdirectory.com/");
        httpRequestMessage.Headers.Add("Accept-Encoding", "gzip, deflate");
        httpRequestMessage.Headers.Add("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8");
        httpRequestMessage.Headers.Add("Cookie", "__utmc=266643403; __utmz=266643403.1537352460.3.3.utmccn=(referral)|utmcsr=google.co.uk|utmcct=/|utmcmd=referral; __utma=266643403.817561753.1532012719.1537357162.1537361568.5; __utmb=266643403; __atuvc=0%7C34%2C0%7C35%2C0%7C36%2C0%7C37%2C48%7C38; __atuvs=5ba2469fbb02458f002");


        var httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;

        var httpContent = httpResponseMessage.Content;
        string result = httpResponseMessage.Content.ReadAsStringAsync().Result;

이 플러그인이 아직 완벽하지는 않지만 두 줄을 주석 처리해야하지만 그럼에도 불구하고 작업을 수행했습니다.

면책 조항 : 나는 Telerik 또는 플러그인 작성자와 관련이 있거나 보증하지 않습니다.


2
이것은 본질적 으로 이것 과 같은 답 이며, 쿠키와 관련된 유일한 부분은 헤더의 마지막 추가입니다. 그 대답의 모든 경고에 주목하십시오
George Mauer

4

나에게 간단한 솔루션은 HttpRequestMessage 객체에 쿠키를 설정하는 것 입니다.

protected async Task<HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken))
{
    requestMessage.Headers.Add("Cookie", $"<Cookie Name 1>=<Cookie Value 1>;<Cookie Name 2>=<Cookie Value 2>");

    return await _httpClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
}

참고 허용 대답은 않는다는 것을 t 이상이보다 더 많은 에지 조건을 처리합니다. http 전용 또는 범위가 지정된 쿠키, 다중 값 쿠키 등과 같은 작업을 수행하는 데 사용할 수 있습니다. 두 번째로 높은 등급의 답변은 이와 동일한 방법을 제안하지만 더 많은 컨텍스트와 설명을 제공합니다
George Mauer

@GeorgeMauer가 옳을 수도 있습니다. 둘 다 "HttpClient (handler)"에서 httpClient를 생성합니다. 내 경우에는 내가 httpClientPool.GetOrCreateHttpClient ()에서 _httpClient를 만드는거야
Waqar UlHaq

1
그러나 당신은 실제로 당신의 대답에서 그것을 보여 주거나 차이점이나 이점을 설명하지 않습니다 (실제로 질문이 아니지만 걱정하지는 않습니다). 나는 무례하지 않으려 고 노력하고 있는데,이 답변이 누구에게 도움이 될 것인지 명확하게하는 것이 중요합니다.
George Mauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.