1. 坑位

最近在重构认证代码,认证过程相当常规:

POST   /open-api/v1/user-info?client_id&timstamp&rd=12345&sign=***&method=hmac
content-type: application/json
payload: { "token":"AA2917B0-C23D-40AB-A43A-4C4B61CC7C74"}

平台显示 :签名校验失败, 排查到平台收到的Post Payload并非预期,阅读本文,解锁正确使用Content-Type标头的姿势。

2. 步步为营

下面是构造HttpClient对象、发起请求的代码:

// 初始化HttpClientFactory
context.Services.AddHttpClient("platform", c =>
{
c.BaseAddress = new Uri("https://alpha-engage.demohost.com/");
c.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
})... // 产生命名HttpClient,发起请求
var client = _clientFactory.CreateClient("platform");
var response = await client.PostAsync($"open-api/v1/user-token/info?{req.AuthString()}",new StringContent(req.ReqPayload.ToString(),Encoding.UTF8) );

平台日志显示,收到的请求payload:

{\"token\":\"AA2917B0-C23D-40AB-A43A-4C4B61CC7C74\"}

额,平台收到的JSON数据被转码了,没有识别出JSON?

明眼人一看,HttpClient请求没有设置Content-Type,接收端没有识别出payload是JSON,接收时进行了转码,生成了错误签名。

① Content-Type是一个Entity Header,指示资源的media type ,可用在请求或者响应中。

② 以上代码中new StringContent(req.ReqPayload.ToString(),Encoding.UTF8)指定了Encoding=UTF-8,却没有指定mediaType,源码默认值:text/plain。


当我尝试添加Content-Type时(下面黄色背景行代码):

 context.Services.AddHttpClient("platform", c =>
{
c.BaseAddress = new Uri("https://alpha-engage.demohost.com/");
c.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header c.DefaultRequestHeaders.Add("content-type", "application/json");
})

此时抛出以下异常:

InvalidOperationException: Misused header name. Make sure request headers are used with
HttpRequestMessage, response headers with HttpResponseMessage, and
content headers with HttpContent objects.

纳尼,HttpContent Headers是啥?Chrome dev tools显示只有两种Header啊?

3. 爬坑

官方资料显示: HTTP Headers被分为如下四类:

--- 信息 举例 对应.NET类型
General Header 可同时作用在请求/响应中,但是与传输数据无关 Upgrade、Connection ---
Request Header 将要获取的资源或客户端本身的信息 Accept、Authorization System.Net.Http.Headers.HttpRequestHeaders
Response Header 响应信息 Location、ETag System.Net.Http.Headers.HttpResponseHeaders
Entity Header 实体Body额外的信息 Content-Length、Content-Type System.Net.Http.Headers.HttpContentHeaders

Content-Type属于Entity Header中的一种。

即便Entity Header既不是请求标头也不是响应标头,它们还是会包含在请求/响应标头术语中(此说法来自官方)。

所以我们在Chrome DevTools没有看到Entity Headers分组,却常在请求/响应标头中看到Content-Type标头。

回到上面的异常,.NET 严格区分四种标头,所以我上面

c.DefaultRequestHeaders.Add("content-type", "application/json");尝试在请求头添加Content-Type标头, 姿势错误, .NET会提示InvalidOperationException异常。

4. 填坑

给这个常规的Post请求 设置正确的Content-Type,

① 对HttpRequestMessage对象Content属性添加Header

 using (var request = new HttpRequestMessage())
{
request.Method = new HttpMethod(method);
request.RequestUri = new Uri(url);
request.Content = new StringContent(payload);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await _httpClient.SendAsync(request);
return response;
}

使用HttpClient.SendAsync(request)

② 对StringContent重载构造函数传参

StringContent某个重载构造函数可直接传参,设置media type,

var response = await client.PostAsync($"open-api/v1/user-token/info?{req.AuthString()}",new StringContent(req.ReqPayload.ToString(),Encoding.UTF8,"application/json") );

干货旁白

  1. 小编对于Http协议有知识漏洞,搬砖时一直关注Chrome DevTools,忽略了还有Entity Header一说。
  2. Content-Type 这个实体标头,会出现了请求/响应标头,指示资源的媒体类型。
  3. .NTE针对4种HTTP Header强化了区别,在实际开发中要灵活使用。

我又踩坑了!如何为HttpClient请求设置Content-Type?的更多相关文章

  1. Flask框架踩坑之ajax跨域请求

    业务场景: 前后端分离需要对接数据接口. 接口测试是在postman做的,今天才开始和前端对接,由于这是我第一次做后端接口开发(第一次嘛,问题比较多)所以在此记录分享我的踩坑之旅,以便能更好的理解,应 ...

  2. Selenium爬虫实践(踩坑记录)之ajax请求抓包、浏览器退出

    上一篇: 使用Selenium截取网页上的图片 前言 最近在搞公司内部系统,累的一批,需要从另一个内部系统导出数据存到数据库做分析,有大量的数据采集工作,又没办法去直接拿到那个系统的接口,太难了,只能 ...

  3. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  4. HttpWebRequest 改为 HttpClient 踩坑记-请求头设置

    HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...

  5. WebForm路由踩坑 ajax请求多次

    WebForm路由踩坑 再次接触Asp.Net WebForm已是4年后的今天,源起新入职的公司,一个老的项目. Web接触的少,那就多动手写写. WebForm1.aspx <body> ...

  6. HttpClient在多线程环境下踩坑总结

    问题现场 在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态. 而且,从程序日志中判断有线程处于han ...

  7. 微信小程序 请求签名接口超时 踩坑路。。

    我们公司一般做开发都是先用测试机的接口调试功能,等功能都调试的差不多了,再换成线上的正式接口,因为正式接口要验证签名. 这几个功能都调试的差不多了,准备换成线上正式接口了,结果却出了问题,提示请求超时 ...

  8. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  9. html2canvas以及domtoimage的使用踩坑总结

    前言 首先做个自我介绍,我是成都某企业的一名刚刚入行约一年的前端,在之前的开发过程中,遇到了问题,也解决了问题,但是在下一次解决相同问题的时候,只对这个问题有一丝丝的印象,还需要从新去查找,于是,我注 ...

  10. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

随机推荐

  1. Redis和Springboot在Windows上面设置开机启动的方法

    Redis和Springboot在Windows上面设置开机启动的方法 背景 同事遇到一个问题 Windows 晚上自动更新服务 然后第二天 Springboot开发的程序没有启动起来. 所以基于此想 ...

  2. [转帖]《Linux性能优化实战》笔记(21)—— 网络性能优化思路

    一. 确定优化目标 优化前,我会先问问自己,网络性能优化的目标是什么?实际上,虽然网络性能优化的整体目标,是降低网络延迟(如 RTT)和提高吞吐量(如BPS 和 PPS),但具体到不同应用中,每个指标 ...

  3. [转帖]iptables ip_conntrack_max 调整

    https://www.diewufeiyang.com/post/583.html 一.概念 ==================== -允许的最大跟踪连接条目:CONNTRACK_MAX(默认值是 ...

  4. [转帖]rsar - Extract data from plain-text sar files

    sar -A -t -f /tmp/sa11 >/tmp/sar11 https://github.com/ryran/rsar When dealing with sysstat sar da ...

  5. ChatGPT 提高工作效率-一例SQL编写的过程

    ChatGPT 提高工作效率-一例SQL编写的过程 前言 遇到一个问题, 怀疑是有一些补丁没有被依赖. 导致第一次更新时没有更新这些没依赖的补丁. 后面更新时又更新了这些游离态的补丁. 导致出现 ol ...

  6. [转帖]将 Cloudflare 连接到互联网的代理——Pingora 的构建方式

    https://zhuanlan.zhihu.com/p/575228941 简介 今天,我们很高兴有机会在此介绍 Pingora,这是我们使用 Rust 在内部构建的新 HTTP 代理,它每天处理超 ...

  7. python+selenium+opencv验证滑块

    我们在使用selenium爬虫的时候在登录时经常会遇到滑块验证码问题,导致登录受阻,正所谓万事开头难. 登录就登录不进去更别提往后的操作的.今天以登录京东后台来演示下如何破解滑块. 一.登录 首先我们 ...

  8. AIGC的隐私安全问题及隐私保护技术

    作者:京东科技 杨博 ChatGPT 才出现两个月,就已经引起了学术界的关注.微软成为ChatGPT母公司OpenAI的合作伙伴,并确认投资百亿美元.同时,微软正计划将 OpenAI 的技术整合到其产 ...

  9. Vant中List列表下拉加载更多

    van-list上只有一层父级元素div,多了可能下拉加载出不来:或者更多 <template> <div class="scholl-declarepage"& ...

  10. 【JS 逆向百例】W店UA,OB反混淆,抓包替换CORS跨域错误分析

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...