Как мне установить cookie в HttpClient's HttpRequestMessage
Я пытаюсь использовать веб-API HttpClient
сделать сообщение для конечной точки, которая требует входа в систему в виде HTTP-cookie, который идентифицирует учетную запись (это только то, что #ifdef
вышли из релизной версии).
Как мне добавить куки в HttpRequestMessage
?
7 ответов
Вот как вы можете установить пользовательское значение cookie для запроса:
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 = client.PostAsync("/test", content).Result;
result.EnsureSuccessStatusCode();
}
Принятый ответ является правильным способом сделать это в большинстве случаев. Однако в некоторых ситуациях вы хотите установить заголовок cookie вручную. Обычно, если вы устанавливаете заголовок "Cookie", он игнорируется, но это потому, что HttpClientHandler
по умолчанию использует его CookieContainer
свойство для печенья. Если вы отключите это, установив UseCookies
в false
Вы можете установить заголовки cookie вручную, и они появятся в запросе, например
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();
}
Для меня простое решение работает для установки файлов cookie в объекте 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);
}
У меня была аналогичная проблема, и для моего приложения AspNetCore 3.1 другие ответы на этот вопрос не работали. Я обнаружил, что настройка именованного HttpClient в моем
Startup.cs
и использование распространения заголовка заголовка Cookie работало отлично. Это также позволяет избежать беспокойства о правильном размещении вашего обработчика и клиента. Обратите внимание: если распространение файлов cookie запроса - это не то, что вам нужно (извините, Op), вы можете установить свои собственные файлы cookie при настройке фабрики клиента.
- Я использовал это руководство от Microsoft - Выполнение HTTP-запросов с помощью IHttpClientFactory в ASP.NET Core
- Распространение заголовка рассматривается в этом разделе - Промежуточное ПО для распространения заголовка
Настроить службы с
IServiceCollection
services.AddHttpClient("MyNamedClient").AddHeaderPropagation();
services.AddHeaderPropagation(options =>
{
options.Headers.Add("Cookie");
});
Настроить с помощью
IApplicationBuilder
builder.UseHeaderPropagation();
- Ввести
IHttpClientFactory
в ваш контроллер или промежуточное ПО. - Создайте своего клиента
using var client = clientFactory.CreateClient("MyNamedClient");
Потратив несколько часов на эту проблему, ни один из ответов выше не помог мне, поэтому я нашел действительно полезный инструмент.
Во-первых, я использовал Fiddler 4 от Telerik для подробного изучения своих веб-запросов.
Во-вторых, я наткнулся на этот полезный плагин для 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, ни автором плагина в любом случае.
Если вы хотите использовать
HttpClient
для отправки запроса, требующего входа пользователя в систему, это означает, что вам необходимо выполнить процесс входа в систему, затем получить файлы cookie и отправить эти файлы cookie на запрос, требующий входа в систему.
Я сделал это при тестировании действия под названием IsLoggedIn. Это действие проверяет, зарегистрирован ли пользователь с помощью файлов cookie в HttpRequest.
Что я сделал при тестировании этого действия:
string Login = JsonConvert.SerializeObject(new LoginViewModel()
{
Email = userFromDb.Email,
Password = "fdfdf@2239",
RememberMe = false
}); ;
StringContent LoginhttpContent = new(Login, Encoding.UTF8, "application/json");
var Login_response = await _httpClient.PostAsync(HelperFunctions.getUrl(HelperFunctions.AcctounController.name, HelperFunctions.AcctounController.Login), LoginhttpContent);
Assert.Equal(HttpStatusCode.OK, Login_response.StatusCode);
//receive cookies from the login response
var cookies = Login_response.Headers.GetValues(HeaderNames.SetCookie);
//Add the cookies to the DefaultRequestHeaders of the _httpClient
_httpClient.DefaultRequestHeaders.Add("Cookie",cookies);
var IsLoggedIn_response = await _httpClient.GetAsync(HelperFunctions.getUrl(HelperFunctions.AcctounController.name, HelperFunctions.AcctounController.IsLoggedIn));
Assert.Equal("true",IsLoggedIn_response.Content.ReadAsStringAsync().Result);
var cookies = new CookieContainer();
var clientHandler = new HttpClientHandler();
clientHandler.CookieContainer = cookies;
var client = new HttpClient(clientHandler, true);