记一次HttpClient使用问题分析

打印 上一主题 下一主题

主题 934|帖子 934|积分 2806

问题

问题是如许的:第三方的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. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表