中的.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和用户ID(如上所述)。理想情况下,我想让我的客户看起来像这样:
public interface ISomeApiClient
{
[Get("/api/somewhere")]
Task<IEnumerable<MyResponseObject>> GetItems();
[Get("/api/somewhere")]
Task<IEnumerable<MyResponseObject>> GetItems(int id);
}
感觉我需要某种请求中间件来进行外发请求,我可以在其中添加这两个标题。如果它们是静态的,我只会装饰整个接口,但是因为这些是行不通的值。
我在文档中找不到任何帮助,并且会欣赏任何指示。
Refit Docs现在解释了如何做到这一点
https://github.com/reactiveui/reefit#reducing-header-boilerplate-with-delegatingHandlers-osthorization-headorization-workered-worked-example- ADD ADD ANDER HANDER: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中注册:
您可以使用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();
}
}