Is there any way to implement an interceptor so that I can call a microservice api from another microservices where all the http call will be intercepted & added jwt token in the header? So that, I don't have to set authorization token each time I request.
In angular there is a concept of HttpInterceptor
. Where each http requests will be intercepted ans added jwt token in the header. Is there any way to achieve that in asp.net core web api?
A simple approach are named clients. Here you add a preconfigured HttpClient instance to your service registry and can access this instance wherever you need it:
builder.Services.AddHttpClient("GitHub", httpClient =>
{
httpClient.BaseAddress = new Uri("https://api.github.com/");
// using Microsoft.Net.Http.Headers;
// The GitHub API requires two headers.
httpClient.DefaultRequestHeaders.Add(
HeaderNames.Accept, "application/vnd.github.v3+json");
httpClient.DefaultRequestHeaders.Add(
HeaderNames.UserAgent, "HttpRequestsSample");
});
Use the httpClient.Default*
properties.
The drawback is, that you don't know how requests must look like when using the instance. One approach to solve this is to create a so-called typed client. Basically a wrapper around HttpClient adding the right configuration and enforcing the correct request and response types.
public class CatalogService : ICatalogService
{
private readonly HttpClient _httpClient;
private readonly string _remoteServiceBaseUrl;
public CatalogService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int? type)
{
var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type);
var responseString = await _httpClient.GetStringAsync(uri);
var catalog = JsonConvert.DeserializeObject<Catalog>(responseString);
return catalog;
}
}
(example from the docs here: https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests)
If you have static values (e.g. a fixed client secret), you can use options to inject them as described here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0
If you get your token from another service, obviously just inject this other service.
You can also configure the HttpClient when adding your typed client to the service registry:
services.AddHttpClient<ICatalogService, CatalogService>(client =>
{
client.BaseAddress = new Uri(Configuration["BaseUrl"]);
});
Configuring the client here is similar to angular injectors in the way, that it separates configuration and client implementation. Example: You could use the same CatalogService class with a catalog server that expects an Authorization header and a server that expects "MySpecialAuth" header without having to take care of those differences in the CatalogService class.
To show the differences in the flow...
Side notes: