Использование VS 2017 .Net 4.5.2
У меня следующий класс
public static class MyHttpClient
{
//fields
private static Lazy<Task<HttpClient>> _Client = new Lazy<Task<HttpClient>>(async () =>
{
var client = new HttpClient();
await InitClient(client).ConfigureAwait(false);
return client;
});
//properties
public static Task<HttpClient> ClientTask => _Client.Value;
//methods
private static async Task InitClient(HttpClient client)
{
//resey headers
client.DefaultRequestHeaders.Clear();
//Set base URL, NOT thread safe, which is why this method is only accessed via lazy initialization
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["baseAddress"]);//TODO: get from web.config? File? DB?
//create new request to obtain auth token
var request = new HttpRequestMessage(HttpMethod.Post, "/ouath2/token"); //TODO: get from web.config? File? DB? prob consts
//Encode secret and ID
var byteArray = new UTF8Encoding().GetBytes($"{ConfigurationManager.AppSettings["ClientId"]}:{ConfigurationManager.AppSettings["ClientSecret"]}");
//Form data
var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("grant_type", "refresh_token"));
formData.Add(new KeyValuePair<string, string>("refresh_token", ConfigurationManager.AppSettings["RefreshToken"]));
//set content and headers
request.Content = new FormUrlEncodedContent(formData);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
//make request
var result = await HttpPost(request, client).ConfigureAwait(false);
//set bearer token
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", (string)result.access_token);
//TODO: error handle
}
private static async Task<dynamic> HttpPost(HttpRequestMessage formData, HttpClient client)
{
using (var response = await client.SendAsync(formData).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();//TODO: handle this
return await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false);
}
}
}
Все еще в процессе, но я наткнулся на загвоздку.
Это отлично работает, если токен нужно получить только один раз в жизни приложения, однако API, о котором я говорю, использует короткоживущие токены-носители (15 минут).
Поскольку я использую HttpClient как статический объект для повторного использования, я не могу изменить заголовки запроса по умолчанию, поскольку они не являются потокобезопасными. Но я должен запрашивать токен на предъявителя каждые 15 минут.
Как мне получить новый токен-носитель и установить заголовок по умолчанию в этом конкретном сценарии?
HttpClient
:PostAsync
,GetAsync
и т. Д. Это просто методы фасада / оболочки дляSendAsync
, поэтомуGetAsync/PostAsync
подойдут.RequestMessage
является потокобезопасным, поскольку в некотором смысле локален. Я немного расширю пример 16.03.2018new tokens here!
. Вы должны хранить их и использовать в последующих запросах, токенах доступа для общих запросов, токенах обновления для запроса токенов обновления. 16.03.2018SendAsync
для автоматического применения этих заголовков, но вам нужно будет откуда-то получить токен. 16.03.2018bool
, чтобы проверить, произошло ли обновление. Например, это может бытьstatic bool
- я не уверен, где должна производиться проверка. Вы можете уточнить? 04.02.2019