启动后如何创建命名客户端?
How to create named client after startup?
对于我的应用程序,我需要为 HttpRequests 创建一个命名的客户端。我可以在 Startup 中创建一个命名的客户端。为了访问它,我注入了一个“IHttpClientFactory”并从中创建了一个客户端。但是客户端需要有一个访问令牌作为授权 header,而我无法在 Startup 中创建令牌。因此,我需要一种在 Startup class 之外创建命名客户端的方法。我已经尝试将“IServiceCollection”注入控制器。但这不起作用。
或者是否有一种方法可以在启动时创建命名客户端后对其进行编辑?
您可以使用 Polly 向您的客户端添加策略处理程序。如果请求 returns a 401 Unauthorized,则可以添加逻辑。因此,例如获取使用客户端刷新不记名令牌并为当前请求设置它的服务。这只是一个快速的解决方案,也许还有更优雅的解决方案。但如果您的令牌过期,这也会派上用场。因为然后它会自动刷新。
services.AddHttpClient("YourClient")
.AddPolicyHandler((provider, request) =>
{
return Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
.RetryAsync(1, async (response, retryCount, context) =>
{
var service = provider.GetRequiredService<IYourService>();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", await service.RefreshToken());
});
});
与@Ruben-J 发布的解决方案类似的解决方案是创建一个自定义 HttpMessageHandler,它为通过 request-time.[=14 处的 HttpClient 发出的请求分配授权 header =]
您可以创建一个自定义的 HttpMessageHandler,它可以在 Startup 中分配给命名的 HttpClient,如下所示:
public class YourHttpMessageHandler : DelegatingHandler
{
private readonly IYourTokenProviderService _yourTokenProviderService;
public YourHttpMessageHandler(IYourTokenProviderService yourTokenProviderService)
: base()
{
_yourTokenProviderService = yourTokenProviderService;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = SendAsyncWithAuthToken(request, cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
await _yourTokenProviderService.RefreshTokenAsync();
response = SendAsyncWithAuthToken(request, cancellationToken);
}
return response;
}
private async Task<HttpResponseMessage> SendWithAuthTokenAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _yourTokenProviderService.Token);
return await base.SendAsync(request, cancellationToken);
}
}
然后您在启动中配置您的服务并命名为 HttpClient:
public virtual void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IYourTokenProviderService, YourTokenProviderService>();
services.AddTransient<YourHttpMessageHandler>();
services.AddHttpClient<IYourNamedHttpClient, YourNamedHttpClient>()
.AddHttpMessageHandler<YourHttpMessageHandler>();
...
}
值得注意的是,Polly 的当前实现 AddPolicyHandler
也在添加自己的 DelegatingHandler。
有关更多背景信息,请参阅 Microsoft documentation on adding DelegatingHandler's. Here is also great series of articles from Steve Gordon.
对于我的应用程序,我需要为 HttpRequests 创建一个命名的客户端。我可以在 Startup 中创建一个命名的客户端。为了访问它,我注入了一个“IHttpClientFactory”并从中创建了一个客户端。但是客户端需要有一个访问令牌作为授权 header,而我无法在 Startup 中创建令牌。因此,我需要一种在 Startup class 之外创建命名客户端的方法。我已经尝试将“IServiceCollection”注入控制器。但这不起作用。
或者是否有一种方法可以在启动时创建命名客户端后对其进行编辑?
您可以使用 Polly 向您的客户端添加策略处理程序。如果请求 returns a 401 Unauthorized,则可以添加逻辑。因此,例如获取使用客户端刷新不记名令牌并为当前请求设置它的服务。这只是一个快速的解决方案,也许还有更优雅的解决方案。但如果您的令牌过期,这也会派上用场。因为然后它会自动刷新。
services.AddHttpClient("YourClient")
.AddPolicyHandler((provider, request) =>
{
return Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
.RetryAsync(1, async (response, retryCount, context) =>
{
var service = provider.GetRequiredService<IYourService>();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", await service.RefreshToken());
});
});
与@Ruben-J 发布的解决方案类似的解决方案是创建一个自定义 HttpMessageHandler,它为通过 request-time.[=14 处的 HttpClient 发出的请求分配授权 header =]
您可以创建一个自定义的 HttpMessageHandler,它可以在 Startup 中分配给命名的 HttpClient,如下所示:
public class YourHttpMessageHandler : DelegatingHandler
{
private readonly IYourTokenProviderService _yourTokenProviderService;
public YourHttpMessageHandler(IYourTokenProviderService yourTokenProviderService)
: base()
{
_yourTokenProviderService = yourTokenProviderService;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = SendAsyncWithAuthToken(request, cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
await _yourTokenProviderService.RefreshTokenAsync();
response = SendAsyncWithAuthToken(request, cancellationToken);
}
return response;
}
private async Task<HttpResponseMessage> SendWithAuthTokenAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _yourTokenProviderService.Token);
return await base.SendAsync(request, cancellationToken);
}
}
然后您在启动中配置您的服务并命名为 HttpClient:
public virtual void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IYourTokenProviderService, YourTokenProviderService>();
services.AddTransient<YourHttpMessageHandler>();
services.AddHttpClient<IYourNamedHttpClient, YourNamedHttpClient>()
.AddHttpMessageHandler<YourHttpMessageHandler>();
...
}
值得注意的是,Polly 的当前实现 AddPolicyHandler
也在添加自己的 DelegatingHandler。
有关更多背景信息,请参阅 Microsoft documentation on adding DelegatingHandler's. Here is also great series of articles from Steve Gordon.