Как создать именованный клиент после запуска? - PullRequest
1 голос
/ 27 мая 2020

Для моего приложения мне нужно создать именованный клиент для HttpRequests. Я могу создать именованный клиент в Startup. И для доступа к нему я ввожу « IHttpClientFactory » и создаю из него клиента. Но у клиента должен быть токен доступа в качестве заголовка авторизации, и я не могу создать токен в Startup. Поэтому мне нужен способ создать именованного клиента вне класса Startup. Я уже пробовал ввести " IServiceCollection " в контроллер. Но это не работает.

Или, может быть, есть способ отредактировать именованный клиент после того, как он уже создан при запуске?

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

Решение, аналогичное тому, что опубликовано @ Ruben-J, заключается в создании настраиваемого HttpMessageHandler, который назначает заголовок авторизации запросам, сделанным через HttpClient во время запроса.

Вы можете создать настраиваемый HttpMessageHandler, который может быть назначен именованному HttpClient в Startup следующим образом:

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 в Startup:

public virtual void ConfigureServices(IServiceCollection services) 
{
    ...
    services.AddTransient<IYourTokenProviderService, YourTokenProviderService>();
    services.AddTransient<YourHttpMessageHandler>();

    services.AddHttpClient<IYourNamedHttpClient, YourNamedHttpClient>()
        .AddHttpMessageHandler<YourHttpMessageHandler>();
    ...
}

Стоит отметить, что текущая реализация Polly's AddPolicyHandler также добавляет свой собственный DelegatingHandler. Дополнительную информацию см. В документации Microsoft по добавлению DelegatingHandler. Вот также отличная серия статей Стива Гордона .

0 голосов
/ 27 мая 2020

Вы можете использовать Polly для добавления обработчика политики вашему клиенту. Затем вы можете добавить logi c, если запрос возвращает 401 Unauthorized. Так, например, получите свою службу, которая использует клиента для обновления sh токена-носителя, а также установите его для текущего запроса. Это просто быстрое решение, и, возможно, есть более элегантные решения. Но это также пригодится, если срок действия вашего токена истечет. Потому что тогда он будет обновлен автоматически.

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());
                    });
            });
...