pet*_*low 6 c# cookies dotnet-httpclient asp.net-core
我们有一个 Web API (.NET Core 5),它将请求传递到另一个远程 Web API。
Web API 从传入请求中获取一些 cookie,并将它们附加到传出请求中。
通常情况下,这工作正常,我们会看到请求 cookie 到达远程 Web API。
但是,当同时发送多个请求时,一个传入请求的 cookie 会以某种方式泄漏到另一个请求的传出请求中。
当使用完全独立的用户和完全独立的浏览器时,甚至会发生这种情况。
我尝试过并确认过的事情:
将 cookie 从传入请求复制到传出请求的代码工作得很好。事实上,即使远程 API 上出现的 cookie 被“泄露”,我的自定义日志记录表明它仍然按预期工作
我可以在远程 Web API 上(在其原始 IIS 日志中)看到预期/泄漏的请求 cookie,因此不可能是远程 API 将其添加到其管道中的请求中。
添加了对 HttpClient 调用的日志记录,但看不到正在发送的意外 cookie。
这在本地不会发生
我的感觉是 HttpClient 中发生了一些事情?
更新 1我添加了日志记录CopyCookieHandler,它只创建一次并被所有请求重用
更新2我刚刚读到HttpMessageHandler实例导致CookieContainer对象被共享...这可能可以解释这一点... https://learn.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>();
Run Code Online (Sandbox Code Playgroud)
在哪里
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);
}
}
Run Code Online (Sandbox Code Playgroud)
是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;
}
}
Run Code Online (Sandbox Code Playgroud)
事实证明,默认情况下,HttpClientHandler会将响应 cookie 存储在 a 中CookieContainer,然后将它们附加到下一个请求中。
这解释了为什么我在远程 API 的请求上看到额外的 cookie,但它们实际上来自先前完成的请求的响应。
该文档引导我解决了这个问题
所以通过添加这段代码:
services.AddHttpClient<IRemoteService, RemoteService>()
.ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseCookies = false,
};
})
.AddHttpMessageHandler<CopyCookieHandler>();
Run Code Online (Sandbox Code Playgroud)
将阻止HttpClientHandler在您的 请求之间共享您的 cookie HttpClient。
| 归档时间: |
|
| 查看次数: |
3558 次 |
| 最近记录: |