【发布时间】:2018-03-15 16:12:48
【问题描述】:
使用 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 分钟请求一次 Bearer 令牌。
在这种特定情况下,我将如何获得新的不记名令牌并设置默认标头?
【问题讨论】:
-
通常刷新令牌的寿命比访问令牌长。如果是这样,一个常见的场景是在收到 HTTP403 后请求一个新的令牌。使用 http 客户端,这很容易在处理程序中实现。所以;你有一个实际的刷新令牌吗?如果是这样;持续时间够长吗?
-
刷新令牌是长寿命的,用它来获取一个新的不记名令牌,不记名令牌是短命的(15分钟)。我把“刷新”而不是“承载”,错字是固定的
标签: c# rest dotnet-httpclient