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 会以某种方式泄漏到另一个 的传出请求中。
甚至在使用完全独立的用户和完全独立的浏览器时也会发生这种情况。
我已经尝试并确认的事情:
将 cookie 从传入请求复制到传出请求的代码工作得很好。事实上,即使出现在远程 API 上的 cookie 被“泄露”,我的自定义日志记录表明它仍然按预期工作
我可以在远程 Web API 上看到 expected/leaky 请求 cookie(在其原始 IIS 日志中),所以它不可能是远程 API 将其添加到其管道中的请求中。
向 HttpClient 调用添加了日志记录,但看不到正在发送的意外 cookie。
本地不会发生这种情况
我的感觉是 HttpClient 中发生了某种事情??
更新 1 我将日志记录添加到 CopyCookieHandler
,它只创建一次并被所有请求重复使用
更新 2 我刚刚读到 HttpMessageHandler
个实例导致 CookieContainer
个对象被共享......这可能解释了这个... https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#cookies
第一个 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,但它们实际上来自先前完成的请求的响应。
此文档引导我进行修复
所以通过添加此代码:
services.AddHttpClient<IRemoteService, RemoteService>()
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseCookies = false,
};
})
.AddHttpMessageHandler<CopyCookieHandler>();
将阻止 HttpClientHandler
在您的 HttpClient
请求之间共享您的 cookie。
我们有一个 Web API (.NET Core 5),它将请求传递到另一个远程 Web API。
Web API 从传入请求中获取一些 cookie 并将它们附加到传出请求中。
通常这工作正常,我们看到请求 cookie 到达远程 Web API。
但是当同时发送多个请求时,来自一个传入请求的 cookie 会以某种方式泄漏到另一个 的传出请求中。
甚至在使用完全独立的用户和完全独立的浏览器时也会发生这种情况。
我已经尝试并确认的事情:
将 cookie 从传入请求复制到传出请求的代码工作得很好。事实上,即使出现在远程 API 上的 cookie 被“泄露”,我的自定义日志记录表明它仍然按预期工作
我可以在远程 Web API 上看到 expected/leaky 请求 cookie(在其原始 IIS 日志中),所以它不可能是远程 API 将其添加到其管道中的请求中。
向 HttpClient 调用添加了日志记录,但看不到正在发送的意外 cookie。
本地不会发生这种情况
我的感觉是 HttpClient 中发生了某种事情??
更新 1 我将日志记录添加到
CopyCookieHandler
,它只创建一次并被所有请求重复使用更新 2 我刚刚读到
HttpMessageHandler
个实例导致CookieContainer
个对象被共享......这可能解释了这个... https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#cookies
第一个 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,但它们实际上来自先前完成的请求的响应。
此文档引导我进行修复
所以通过添加此代码:
services.AddHttpClient<IRemoteService, RemoteService>()
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseCookies = false,
};
})
.AddHttpMessageHandler<CopyCookieHandler>();
将阻止 HttpClientHandler
在您的 HttpClient
请求之间共享您的 cookie。