【问题标题】:.NET core set auth header for HttpClient service instance.NET 核心为 HttpClient 服务实例设置身份验证标头
【发布时间】:2020-10-09 14:24:39
【问题描述】:

一些外部服务不提供长期 API 密钥,为了向他们的 API 发出请求,我需要首先发出登录请求,该请求返回 authToken 和 refreshToken。

在我的 .NET 核心应用程序中,我希望有一个服务类,它将从此外部 API 返回数据。

现在我将此服务注册为 Typed HttpClient:

services.AddHttpClient<IExternalService, ExternalService>();

但是这样一来,所有服务方法都必须调用登录方法来获取 authHeader,然后再向此外部 API 发出任何其他请求。

我想避免它并将 authHeader 保存在某处并由所有服务方法使用它,直到它们收到 403 未经授权的响应,然后才调用登录方法以获取新的 authToken

实现此用例的最佳方法是什么?

【问题讨论】:

  • 您是否考虑过使用管理身份验证状态的单例服务?

标签: c# asp.net-core .net-core


【解决方案1】:

可以在客户端创建后添加authHeader

像现在一样添加 http 客户端:

services.AddHttpClient<IExternalService, ExternalService>(); 

你的服务类有一个方法来验证并将标头注入客户端:

public class myService 
{
    private readonly HttpClient _client

    public myService(HttpClient client)
    {
      _client = client;
    }

    private Task Authenticate() 
    { 
        ... your authentication logic here
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        _client.DefaultRequestHeaders.Add("Auth", yourToken);
    }

    public MyMethod()
    {
        try
        {
            _client.get....
        }
        catch() 
        {
          catch the unauthorized exception here and call Authenticate()
        }
    }
}

然后,在所有 api 调用中,放置一个 catch 块来捕获 401、403 错误并在重新调用 api 之前再次调用 authenticate 方法。

*对于最后一部分,我认为您可以查看 Polly 包以自动化此过程。

您也可以只检查响应状态代码而不是捕获异常:

public class myService 
{
    private readonly HttpClient _client

    public myService(HttpClient client)
    {
      _client = client;
    }

    private Task Authenticate() 
    { 
        ... your authentication logic here
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        _client.DefaultRequestHeaders.Add("Auth", yourToken);
    }

    public MyMethod()
    {
        try
        {
           var retry = false;
           do
           {
               var response = _client.get....
               if (!response.IsSuccessStatusCode)
               {
                    if(response.StatusCode == HttpStatusCode.401 || response.StatusCode == HttpStatusCode.403)
                    {
                         Authenticate();
                         retry = true;
                    }                    
               }
            }
            catch() 
            {
            }
        }
        while (retry);
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 2018-05-29
    • 2019-11-03
    • 2019-02-23
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2011-04-28
    相关资源
    最近更新 更多