问题
问题是如许的:第三方的webapi,需要先调用登陆接口获取Cookie,访问别的接口时携带Cookie信息。
但使用HttpClient类调用登陆接口,返回的Headers中没有找到Cookie信息。
分析
首先,使用Postman测试该登陆接口,正常返回Cookie信息,说明是HttpClient访问接口出了问题。
通过调试发现,明明使用的Post请求,返回的HttpResponseMessage却显示为GET请求。
下载WireShark网络分析工具,抓包发现,Post请求返回了302,且返回中是携带了Cookie信息的,随即又进行了GET请求到重定向的地点,返回的信息中没有Cookie。302表示请求的资源已被临时移动到另一个位置,客户端应该重定向到的新位置。因此,可以知道是HttpClient自动进行了重定向。
解决
方法也很简单,对于登陆接口,直接禁用自动跟随重定向即可:- public async Task<HttpResponseMessage> PostAuthAsync(string url, CancellationToken cancellationToken = default(CancellationToken))
- {
- using var httpClientHandler = new HttpClientHandler()
- {
- // 禁用自动跟随重定向
- AllowAutoRedirect = false
- };
- using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
- using var client = new HttpClient(httpClientHandler);
- return await client.SendAsync(request, cancellationToken);
- }
复制代码 从返回中获取指定的Cookie信息:- string GetCookieFromResponseHeader(HttpResponseHeaders headers)
- {
- if (headers.TryGetValues("Set-Cookie", out IEnumerable<string> setCookieHeaders))
- {
- foreach (var headerValue in setCookieHeaders)
- {
- foreach (var cookieHeader in headerValue.Split(';'))
- {
- var parts = cookieHeader.Split('=');
- if (parts.Length == 2 && parts[0] == cookieName)
- return parts[1];
- }
- }
- }
- return string.Empty;
- }
复制代码 访问别的接口时,添加Cookie信息:- public async Task<HttpResponseMessage> PostAsync(string url, string cookie, string jsonData, CancellationToken cancellationToken = default(CancellationToken))
- {
- var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
- var httpClient = _httpClientFactory.CreateClient();
- string cookieHeader = $"{cookieName}={cookie}";
- httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Cookie", cookieHeader);
- return await httpClient.PostAsync(url, content, cancellationToken);
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |