ASP.NET Core 2 получает файлы cookie от HttpResponseMessage
В настоящее время я работаю над проектом, написанным на ASP.NET Core 2, и пытаюсь получить файл JSON со стороннего веб-сайта. Проблема в том, что для получения данных с этого сайта требуется несколько файлов cookie. Я реализовал типизированный HttpClient в моем файле Startup.cs следующим образом:
services.AddHttpClient<IMyClient, MyClient>().ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseCookies = true,
UseDefaultCredentials = true,
CookieContainer = new CookieContainer()
};
});
Есть ли способ получить доступ к CookieContainer, чтобы использовать метод CookieContainer.GetCookies(), чтобы я мог копировать различные файлы cookie, такие как Session Cookie и некоторые токены проверки, из HttpResponseMessage?
Извините, если я делаю что-то не так, это мой первый пост.
РЕДАКТИРОВАТЬ
Получил это, добавив HttpMessageHandler в конвейер запросов
services.AddHttpClient<IMyHttpClient, MyHttpClient>()
.AddHttpMessageHandler<MyMessageHandler>();
и измените информацию заголовка http в HttpMessageHandler
public class MyMessageHandler : DelegatingHandler
{
private readonly CookieContainer _cookies;
public MyMessageHandler()
{
_cookies = new CookieContainer();
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage message, CancellationToken cancellationToken)
{
try
{
if (_cookies.Count == 0 && message.RequestUri.Host.Contains("example.com"))
{
// Simulate the Request
var getCookieMesssage = new HttpRequestMessage()
{
RequestUri = new Uri("http://www.example.com/"),
Content = message.Content,
Method = HttpMethod.Get,
};
// Simulate User Agent
foreach(var agent in message.Headers.UserAgent)
{
getCookieMesssage.Headers.UserAgent.Add(agent);
}
var testResponse = await base.SendAsync(getCookieMesssage, cancellationToken);
if (testResponse.Headers.TryGetValues("Set-Cookie", out var newCookies))
{
foreach (var item in SetCookieHeaderValue.ParseList(newCookies.ToList()))
{
var uri = new Uri(message.RequestUri, item.Path.Value);
// Add parsed cookies to CookieContainer
_cookies.Add(uri, new Cookie(item.Name.Value, item.Value.Value, item.Path.Value));
}
}
// Add parsed cookies to the header of the HttpRequestMessage
message.Headers.Add("Cookie", _cookies.GetCookieHeader(message.RequestUri));
}
// get response
var response = await base.SendAsync(message, cancellationToken).ConfigureAwait(false);
return response;
}catch(Exception ex)
{
throw ex;
}
}
}
Этот подход получает все куки из заголовка Set-Cookie и добавляет их в заголовок Cookie запроса.
1 ответ
Если MyClient
это пользовательская реализация HttpClient
Вы можете перегрузить конструктор, чтобы сохранить ссылку на HttpClientHandler
:
public MyClient(HttpMessageHandler handler)
: base(handler)
{
Handler = handler;
}
public MyClient(HttpMessageHandler handler, bool disposeHandler)
: base(handler, disposeHandler )
Handler = handler;
)
public HttpMessageHandler Handler { get; }
Ответ от вашего редактирования неясен, поэтому я резюмировал его здесь. Кроме того, нет необходимости явно устанавливатьHttpClientHandler.UseCookies = true
или за то, чтобы CookieContainer
.
Чтобы получить файлы cookie во время звонка, вы можете просто прочитать "Set-Cookie"
заголовок ответа:
HttpResponseMessage response = await httpClient.GetAsync(uri);
IEnumerable<string> cookies = response.Headers.SingleOrDefault(header => header.Key == "Set-Cookie")?.Value;
$.ajax({
url: "https://localhost:44330/api/Records",
type: 'POST',
contentType:"application/json; charset=utf-8",
dataType:"json",
data: JSON.stringify(formdata),
// Fetch the stored token from localStorage and set in the header
headers: {"Authorization":'Bearer '+data.data.token},
success: function(datas) {}
});