HttpClient 正在从其他请求的响应中发送请求 cookie

HttpClient is sending request cookies from other requests' responses

我们有一个 Web API (.NET Core 5),它将请求传递到另一个远程 Web API。

Web API 从传入请求中获取一些 cookie 并将它们附加到传出请求中。

通常这工作正常,我们看到请求 cookie 到达远程 Web API。

但是当同时发送多个请求时,来自一个传入请求的 cookie 会以某种方式泄漏到另一个 的传出请求中。

甚至在使用完全独立的用户和完全独立的浏览器时也会发生这种情况。

我已经尝试并确认的事情:

第一个 API 使用 HttpClient 的设置:

services.AddHttpContextAccessor()
services.AddHttpClient<IRemoteService, RemoteService>()
                .AddHttpMessageHandler<CopyCookieHandler>();
services.AddTransient<CopyCookieHandler>();

哪里

public class RemoteService : IRemoteService
{
   private HttpClient _client;
   public RemoteService(HttpClient client)
   {
      _client = client;
   }

   public async Task Get()
   {
      var request = new HttpRequestMessage("POST", "http://example.com");
      await MakeCall(request);
   }
}

CopyCookieHandler是:

public class CopyCookieHandler : DelegatingHandler
{
  public IHttpContextAccessor _context;
  public CopyCookieHandler(IHttpContextAccessor context)
  {
     _context = context;
  }

  protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  {
     //Copies the incoming request cookie and adds to the outgoing request
     var productId = _context.HttpContext.Request.Cookies["productId"];
     request.Headers.Add(HeaderNames.Cookie, $"productId={productId});

     var response = await base.SendAsync(request, cancellationToken);
     return response;
  }
}

事实证明,默认情况下,HttpClientHandler 会将响应 cookie 存储在 CookieContainer 中,然后将它们附加到下一个请求中。

这解释了为什么我在远程 API 的请求中看到额外的 cookie,但它们实际上来自先前完成的请求的响应。

此文档引导我进行修复

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#cookies-1

所以通过添加此代码:

services.AddHttpClient<IRemoteService, RemoteService>()
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        return new HttpClientHandler()
        {
            UseCookies = false,
        };
    })
    .AddHttpMessageHandler<CopyCookieHandler>();

将阻止 HttpClientHandler 在您的 HttpClient 请求之间共享您的 cookie。