2

我在使用 IHttpClientFactory 的 .NET Core 3.1 应用程序中使用 Refit (5.1.67) 作为我的 HttpClient 包装器。

我调用的 API 使用客户端凭据令牌进行保护。

我正在用这个注册客户:

services.AddRefitClient<ISomeApiClient>().ConfigureHttpClient(c =>
            c.BaseAddress = new Uri(Configuration["BaseUrlFromConfig"]));

客户端具有如下所示的方法:

public interface ISomeApiClient
{
    [Get("/api/somewhere")]
    Task<IEnumerable<MyResponseObject>> GetItems([Header("X-User-Id")] string userId, [Header("Authorization")] string accessToken);

    [Get("/api/somewhere-else")]
    Task<MyResponseObject> GetItem([Header("X-User-Id")] string userId, [Header("Authorization")] string accessToken, int id);
}

我要避免的是每次调用端点时都必须显式传递 accessToken 和 userId (如上)。理想情况下,我想让我的客户看起来像这样:

public interface ISomeApiClient
{
    [Get("/api/somewhere")]
    Task<IEnumerable<MyResponseObject>> GetItems();

    [Get("/api/somewhere")]
    Task<IEnumerable<MyResponseObject>> GetItems(int id);
}

感觉就像我需要某种用于传出请求的请求中间件,我可以在其中添加这两个标头。如果它们是静态的,我只会装饰整个界面,但因为这些是无法工作的运行时值。

我在文档中找不到关于这个的任何帮助,并且希望得到任何指示。

4

2 回答 2

1

改装文档现在解释了如何做到这一点

https://github.com/reactiveui/refit#reducing-header-boilerplate-with-delegatinghandlers-authorization-headers-worked-example

添加标头处理程序:

class AuthHeaderHandler : DelegatingHandler
 {
    private readonly IAuthTokenStore authTokenStore;

    public AuthHeaderHandler(IAuthTokenStore authTokenStore)
    {
         this.authTokenStore = authTokenStore;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var token = await authTokenStore.GetToken();

        //potentially refresh token here if it has expired etc.

        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
    }
}

然后在注册客户端时在 Startup.cs 中注册:

services.AddTransient<AuthHeaderHandler>();

services.AddRefitClient<ISomeThirdPartyApi>()
        .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
        .AddHttpMessageHandler<AuthHeaderHandler>();

于 2021-07-22T10:52:28.760 回答
0

您可以使用 DI 将您的客户注入您需要的地方。我们像这样使用它:

[ApiController]
public class ValuesController : ControllerBase
{
private readonly ISomeApiClient_client;

public ValuesController(ISomeApiClient client)
{
   _client = client;
   httpClient.DefaultRequestHeaders.Authorization =
                     new AuthenticationHeaderValue("Bearer", "Your Oauth token");
}

[HttpGet("/")]
public async Task<ActionResult<Reply>> Index()
{
  return await _client.GetMessageAsync();
}
}
于 2021-03-19T11:08:51.187 回答