I am using Refit (5.1.67) as my HttpClient wrapper, in a .NET Core 3.1 app using IHttpClientFactory.
The API I am calling is secured using a client credentials token.
I am registering the client with this:
services.AddRefitClient<ISomeApiClient>().ConfigureHttpClient(c =>
c.BaseAddress = new Uri(Configuration["BaseUrlFromConfig"]));
The client has methods that look like this:
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);
}
What I want to avoid is having to explicitly pass accessToken and userId every time I call an endpoint (like above). Ideally, I want to have my client look like this:
public interface ISomeApiClient
{
[Get("/api/somewhere")]
Task<IEnumerable<MyResponseObject>> GetItems();
[Get("/api/somewhere")]
Task<IEnumerable<MyResponseObject>> GetItems(int id);
}
It feels like I need some sort of request middleware for outgoing requests, where I can add these two headers. If they were static I would just decorate the whole interface but because these are runtime values that will not work.
I cannot find any help on this one in the docs, and would appreciate any pointers.
Refit docs now explain how to do this
Add a header handler:
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);
}
}
then register in Startup.cs when registering the client:
services.AddTransient<AuthHeaderHandler>();
services.AddRefitClient<ISomeThirdPartyApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
.AddHttpMessageHandler<AuthHeaderHandler>();