C# HttpClient刷新 token 策略

标签 c# httpclient delegatinghandler

自微软 recommends HttpClient 创建一次并在程序的整个生命周期中重复使用,我想知道如何更新 DefaultRequestHeaders 例如, token 已过期并需要刷新。

DefaultRequestHeaders 不仅仅是线程安全的(据我所知),而且那里定义的 header 列表由所有潜在的待处理请求共享。 Clear() 列表和 Add() 带有新 token 的 header ,似乎不是明智之举。

<小时/>

更新

更准确地说,我不想/不需要更改每个请求的请求 header 。仅当我收到 HTTP 401 状态代码时。

最佳答案

当您在 DI 容器注册表阶段注册 IHttpClient 时,将消息处理程序与 HttpClient 连接起来,或者使用其他模式(例如工厂或单例)来返回带有自定义消息处理程序的 IHttpClient 实例。检查出站调用并添加必要的 header 。

https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers

示例 header 消息处理程序

class MessageHandler1 : DelegatingHandler
    {


    private int _count = 0;

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        System.Threading.Interlocked.Increment(ref _count);
        request.Headers.Add("X-Custom-Header", _count.ToString());
        return base.SendAsync(request, cancellationToken);
    }
}

示例记录器消息处理程序:

class LoggingHandler : DelegatingHandler

{
    StreamWriter _writer;

public LoggingHandler(Stream stream)
{
    _writer = new StreamWriter(stream);
}

protected override async Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
    var response = await base.SendAsync(request, cancellationToken);

    if (!response.IsSuccessStatusCode)
    {
        _writer.WriteLine("{0}\t{1}\t{2}", request.RequestUri, 
            (int)response.StatusCode, response.Headers.Date);
    }
    return response;
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        _writer.Dispose();
    }
    base.Dispose(disposing);
}

}

将其添加到管道

HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());

线程问题

关于线程问题或并发性,SendAsync 方法上的 HttpRequestMessage 参数将针对每个请求。如果将 header 添加到 request.Headers 集合中,您将仅更新该请求实例的 header (即不是全局的)

或者使用 request.Headers 实例上的 Authorization 属性:

request.Headers.Authorization = new AuthenticationHeaderValue("bearer", bearerToken);

请参阅下面的 MSDN 链接

https://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage

如果您在 HttpClient 的静态、共享、单例、Lifestyle.Singleton 等实例上使用 DefaultRequestHeaders,那么您将遇到线程问题,并且需要适当的同步来更新 DefaultRequestHeaders 集合。

关于C# HttpClient刷新 token 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49953560/

相关文章:

c# - 使用 JSON 架构正确创建 .NET 类

c# - 使用基于声明的有效 JWT 保护 webapi

c# - VB.Net 相当于 C# 中的 ^ 运算符

c# - 如何将连续的语音转文本服务(使用 MS 认知服务)包含到写入页面文本框的 ASP.NET Web 应用程序中?

c# - Polly "retry"在第一次失败重试尝试时抛出 TaskCanceledException

c# - 单元测试 DelegatingHandler

android - 如何获取 HTTPResponse 的 URL

azure - 单例 httpClient 到 AppService 的单个实例

php - Android JSON HttpClient 使用 HttpResponse 将数据发送到 PHP 服务器