我正在使用IHttpClientFactory通过Net Core 2.2向两个外部API发送请求并接收HTTP响应。
我正在寻找一种好的策略,使用存储在appsettings.json中的刷新令牌来获取新的访问令牌。当当前请求返回403或401错误时,需要请求新的访问令牌。当获取到新的访问和刷新令牌后,需要更新appsettings.json中的值以便在后续请求中使用。
我使用两个客户端发送请求到两个不同的API,但只有一个使用令牌身份验证机制。
我已经实现了一些简单的东西,但是我正在寻找一种更优雅的解决方案,可以在当前令牌过期时动态更新标头:
我已在Startup.ConfigureServices方法中注册了IHttpClientFactory,如下所示:
services.AddHttpClient();
一旦注册,我将使用它来调用两个不同的API,第一种方法是:
public async Task<AirCallRequest> GetInformationAsync(AirCallModel model)
{
try
{
CandidateResults modelCandidateResult = null;
var request = new HttpRequestMessage(HttpMethod.Get,
"https://*******/v2/*****");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _appSettings.Value.Token);
var clientJAAPI = _httpClientFactory.CreateClient();
var responseclientJAAPI = await clientJAAPI.SendAsync(request);
if (responseclientJAAPI.IsSuccessStatusCode)
{
modelCandidateResult = await responseclientJAAPI.Content
.ReadAsAsync<CandidateResults>();
....
}
if ((responseclientJAAPI .StatusCode.ToString() == "Unauthorized")
{
await RefreshAccessToken();
//Calls recursively this method again
return await GetInformationAsync(model);
}
return null;
}
catch (Exception e)
{
return null;
}
}
刷新令牌的方法如下:
private async Task RefreshAccessToken()
{
var valuesRequest = new List<KeyValuePair<string, string>>();
valuesRequest.Add(new KeyValuePair<string, string>("client_id", "*****"));
valuesRequest.Add(new KeyValuePair<string, string>("client_secret","****"));
valuesRequest.Add(new KeyValuePair<string, string>("grant_type", "refresh_token"));
valuesRequest.Add(new KeyValuePair<string, string>("refresh_token", "*****"));
RefreshTokenResponse refreshTokenResponse = null;
var request = new HttpRequestMessage(HttpMethod.Post,
"https://*****/connect/token");
request.Content = new FormUrlEncodedContent(valuesRequest);
var clientJAAPI = _httpClientFactory.CreateClient();
var responseclientJAAPI = await clientJAAPI.SendAsync(request);
if (responseclientJAAPI.IsSuccessStatusCode)
{
refreshTokenResponse = await responseclientJAAPI.Content.ReadAsAsync<RefreshTokenResponse>();
//this updates the POCO object representing the configuration but not the appsettings.json :
_appSettings.Value.Token = refreshTokenResponse.access_token;
}
}
注意,我正在更新表示配置的POCO对象,而不是appsettings.json,因此新值存储在内存中。我想更新appsettings.json以供后续请求使用。如果提出的解决方案需要在Startup.ConfigureService中定义Httpclient的主要设置,则需要允许创建不同实例的HttpClien,因为其中一个HttpClient实例(用于调用第二个API的另一个方法)不需要令牌来发送请求。