C#如何使用共享的HttpClient传递cookie

时间:2016-02-29 16:40:41

标签: c# cookies dotnet-httpclient

我有以下设置:

JS客户端 - > Web Api - > Web Api

我需要一直向下发送auth cookie。我的问题是从一个web api发送到另一个。由于与使用FormsAuthentication的旧系统集成,我必须传递auth cookie。

出于性能原因,我在以下字典中共享一个HttpClients列表(每个web api一个):

private static ConcurrentDictionary<ApiIdentifier, HttpClient> _clients = new ConcurrentDictionary<ApiIdentifier, HttpClient>();

因此,给定一个标识符,我可以获取相应的HttpClient。

以下是有效的,但我很确定这是错误的代码:

HttpClient client = _clients[identifier];
var callerRequest = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
string authCookieValue = GetAuthCookieValue(callerRequest);

if (authCookieValue != null)
{
    client.DefaultRequestHeaders.Remove("Cookie");
    client.DefaultRequestHeaders.Add("Cookie", ".ASPXAUTH=" + authCookieValue);
}

HttpResponseMessage response = await client.PutAsJsonAsync(methodName, dataToSend);

// Handle response...

关于这一点的错误是1)在请求中操纵DefaultRequestHeaders似乎是错误的; 2)当共享HttpClient时,可能两个同时发送的请求可能会弄乱cookie。

我一直在寻找一段时间而没有找到解决方案,因为大多数具有匹配问题的实例化每个请求的HttpClient,因此能够设置所需的标头,我试图避免。

有一次,我收到使用HttpResponseMessage的请求。也许这可以激发解决方案。

所以我的问题是:有没有办法使用HttpClient为单个请求设置cookie,这对于使用相同实例的其他客户端是否安全?

1 个答案:

答案 0 :(得分:16)

您可以使用HttpRequestMessage和SendAsync()来代替调用PutAsJsonAsync():

Uri requestUri = ...;
HttpMethod method = HttpMethod.Get /*Put, Post, Delete, etc.*/;
var request = new HttpRequestMessage(method, requestUri);
request.Headers.TryAddWithoutValidation("Cookie", ".ASPXAUTH=" + authCookieValue);
request.Content = new StringContent(jsonDataToSend, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);

更新: 要确保您的HTTP客户端不存储响应中的任何cookie,您需要执行此操作:

var httpClient = new HttpClient(new HttpClientHandler() { UseCookies = false; });

否则,您可能会因使用一个客户端并共享其他Cookie而出现意外行为。