翼度科技»论坛 编程开发 .net 查看内容

记一次HttpClient使用问题分析

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
问题

问题是这样的:第三方的webapi,需要先调用登陆接口获取Cookie,访问其它接口时携带Cookie信息。
但使用HttpClient类调用登陆接口,返回的Headers中没有找到Cookie信息。
分析

首先,使用Postman测试该登陆接口,正常返回Cookie信息,说明是HttpClient访问接口出了问题。
通过调试发现,明明使用的Post请求,返回的HttpResponseMessage却显示为GET请求。
下载WireShark网络分析工具,抓包发现,Post请求返回了302,且返回中是携带了Cookie信息的,随即又进行了GET请求到重定向的地址,返回的信息中没有Cookie。302表示请求的资源已被临时移动到另一个位置,客户端应该重定向到的新位置。因此,可以知道是HttpClient自动进行了重定向。
解决

方法也很简单,对于登陆接口,直接禁用自动跟随重定向即可:
  1. public async Task<HttpResponseMessage> PostAuthAsync(string url, CancellationToken cancellationToken = default(CancellationToken))
  2. {
  3.     using var httpClientHandler = new HttpClientHandler()
  4.     {
  5.         // 禁用自动跟随重定向
  6.         AllowAutoRedirect = false
  7.     };
  8.     using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
  9.     using var client = new HttpClient(httpClientHandler);
  10.     return await client.SendAsync(request, cancellationToken);
  11. }
复制代码
从返回中获取指定的Cookie信息:
  1. string GetCookieFromResponseHeader(HttpResponseHeaders headers)
  2. {
  3.     if (headers.TryGetValues("Set-Cookie", out IEnumerable<string> setCookieHeaders))
  4.     {
  5.         foreach (var headerValue in setCookieHeaders)
  6.         {
  7.             foreach (var cookieHeader in headerValue.Split(';'))
  8.             {
  9.                 var parts = cookieHeader.Split('=');
  10.                 if (parts.Length == 2 && parts[0] == cookieName)
  11.                     return parts[1];
  12.             }
  13.         }
  14.     }
  15.     return string.Empty;
  16. }
复制代码
访问其它接口时,添加Cookie信息:
  1. public async Task<HttpResponseMessage> PostAsync(string url, string cookie, string jsonData, CancellationToken cancellationToken = default(CancellationToken))
  2. {
  3.     var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
  4.     var httpClient = _httpClientFactory.CreateClient();
  5.     string cookieHeader = $"{cookieName}={cookie}";
  6.     httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Cookie", cookieHeader);
  7.     return await httpClient.PostAsync(url, content, cancellationToken);
  8. }
复制代码
来源:https://www.cnblogs.com/louzixl/p/18423507
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具