我正在使用 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;
}
}
refresh Token 方法如下所示:
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)没有t 需要令牌来发送请求。