案例分享-丢失的请求头

· 浏览次数 : 0

小编点评

**问题描述** 在开发过程中,开放API给第三方调用时,需要在HTTP请求中传递一个名为`access_token`的头。然而,在测试环境中无法获取到这个头,而在本地调试时一切正常。 **排查过程** 1. 首先确认本地调试时没有问题,因此问题很可能出在代码层面。 2. 分析请求链路,从浏览器到外网Nginx,再到Kubernetes Ingress,最后到Spring Boot服务。 3. 在每个节点上使用`curl`命令进行测试,排除其他节点的干扰。 4. 发现即使在自己的Spring Boot服务中,也能正常获取`access_token`,因此排除了代码问题。 5. 进一步分析Ingress的配置,发现在Ingress的配置中多加了`Host`头部。 6. 修改测试用例中的`curl`命令,添加`Host`头部,并重新测试。 7. 经过一系列测试和分析,最终确定是Nginx配置中的`underscores_in_headers`参数导致`access_token`头部被丢弃。 **结论与建议** 1. **修改Nginx配置**:修改`underscores_in_headers`参数为`on`或`off`,根据实际需求选择。 2. **修改请求头名称**:将`access_token`修改为`access-token`,以符合HTTP请求头规范。 3. **考虑其他节点的影响**:由于修改请求链路中的参数可能会影响其他节点的处理,建议在实际部署前进行充分的测试和验证。 通过以上步骤,成功解决了测试环境中无法获取`access_token`的问题。

正文

 拍摄于富平中华郡
 

 

背景

今天组内一个小哥找我协助看一个问题,现象是他开放了一个Api给第三方调用,需要在http中传递一个名字为access_token的头,但是发布到测试环境以后却怎么也获取不到这个头,本地调试是没有问题的,希望协助看看。

排查

http传递头还会出问题,这都是很成熟的东西了,大概率是代码写的有问题。我提出看一眼代码,就一行request.getHeader,也不应该出问题,那是哪里出了问题呢?

“弄清楚请求链路,从外到内,从内到外逐个分析”。

冷静下来分析一番以后我觉得可能是请求链路上的其他节点没有正确传递access_token导致,所以我带着小哥大概梳理了一下请求链路,大致是这样(可能和真实的不同,只是按我了解到的):

浏览器->外网nginx->k8s ingress->springboot服务。

接下来就开始从内到外逐个逐个节点测试分析,找出元凶。

1.先进入springboot服务所属的容器内使用curl 127.0.0.1测试,等于自己访问自己,排除其他节点的干扰,结果是可以正常拿到access_token的值,排除代码问题

curl -H 'access_token: xxxx' http://127.0.0.1:8080/xxx

  

2.进入ingress的容器内依然是curl 127.0.0.1测试,这时的请求链路相当于curl->k8s ingress->springboot服务,目的是验证k8s ingress是否会影响请求头的传递。

#这里有个细节是多加了Host: 域名,至于为什么这里留个思考题
curl -H 'Host: 域名' -H 'access_token: xxxx' http://127.0.0.1:8080/xxx

 

3.以此类推测试&分析。

其实在做完第一步的时候我脑袋里突然闪过了答案(很久之前遇到过,一开始没想起来),后面的步骤就没有进行,写在这里只是想把自己排查这类问题的思路和大伙做一个交流,至于答案是什么我先卖个关子,我接下来先普及一个冷知识。

http请求头规范

https://www.rfc-editor.org/rfc/rfc9110.html#name-field-names

 

 

大概意思是请求头的名称应该是由字母(特指英文字母)、数字、- 组成,最好是以字母开头,还特别说了如果请求头包含_可能带来一些问题,有兴趣的可以去了解,这里就不啰嗦了。

真凶

到这里也许你已经发现了一些端倪,前面提到的access_token不正是包含_吗,从rfc文档来看这个头是不符合规范的,所以就在nginx那里翻了车,一起来看下官网的介绍。

https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers

 

解读下这段文字的意思:nginx会将带有_的请求头丢弃,不会往后传递,如果不希望丢弃可以修改underscores_in_headers的值为on或者将ignore_invalid_headers修改为off。

最终处理

1.梳理链路上的nginx,修改underscores_in_headers或者ignore_invalid_headers的值;

2.将access_token修改为access-token,使其符合规范;

最终采用方案2解决,原因很简单,修改请求链路上的参数影响较大,而且不一定能覆盖全,已知的有nginx,保不齐还有slb、iis、apache等,不可控因素太多。

 

 

 

 

与案例分享-丢失的请求头相似的内容:

案例分享-丢失的请求头

拍摄于富平中华郡 背景 今天组内一个小哥找我协助看一个问题,现象是他开放了一个Api给第三方调用,需要在http中传递一个名字为access_token的头,但是发布到测试环境以后却怎么也获取不到这个头,本地调试是没有问题的,希望协助看看。 排查 http传递头还会出问题,这都是很成熟的东西了,大概

[转帖]系统原因导致的丢包问题如何破?

https://developer.aliyun.com/article/68919 简介: 丢包的问题经常碰到,那丢包的问题如何破?今天专家枫凡坐诊为您分析丢包问题,一个案例教你如何排查系统原因导致的丢包问题。 本期分享专家:枫凡,曾就职于安恒信息。目前在阿里云从事ECS产品的技术支持,专注于云计

硬核案例分享,一文带你拆解PHP语言体系下的容器化改造

本文介绍了PHP语言体系应用现代化案例,实现了许多与业务无关的通用性应用改造方案,如PHP应用容器化架构方案、基于Prometheus的弹性伸缩方案等等,为此类型客户提供了一个可参考的案例。

[转帖]实战案例分享:根据 JVM crash 日志定位和分析问题

https://cloud.tencent.com/developer/article/1744442 1. JVM crash了 下面是一份crash report, 下面是截取了crash report的部分,用于分析: # Problematic frame: # V [libjvm.so+0

《社区人员管理》实战案例设计&个人案例分享

设计是一个让人梦想成真过程,开始编码、测试、调试之前进行需求分析和架构设计,才能保证关键方面都做正确

海量监控数据处理如何做,看华为云SRE案例分享

摘要:openGemini的设计和优化都是根据时序数据特点而来,在面对海量运维监控数据处理需求时,openGemini显然更加有针对性。 IT运维诞生于最早的信息化时代。在信息化时代,企业的信息化系统,主要为了满足企业内部管理的需求。通常是集中、可控和固化的烟囱式架构。传统IT运维,以人力运维为主,

Python从零到壹丨图像增强及运算:图像掩膜直方图和HS直方图

摘要:本章主要讲解图像直方图相关知识点,包括掩膜直方图和HS直方图,并通过直方图判断黑夜与白天,通过案例分享直方图的实际应用。 本文分享自华为云社区《[Python从零到壹] 五十二.图像增强及运算篇之图像掩膜直方图和HS直方图》,作者: eastmount。 一.图像掩膜直方图 如果要统计图像的某

[转帖]那些你不知道的 TCP 冷门知识

最近在做数据库相关的事情,碰到了很多TCP相关的问题,新的场景新的挑战,有很多之前并没有掌握透彻的点,大大开了一把眼界,选了几个案例分享一下。 案例一:TCP中并不是所有的RST都有效 背景知识:在TCP协议中,包含RST标识位的包,用来异常的关闭连接。在TCP的设计中它是不可或缺的,发送RST段关

数据驱动测试-从方法探研到最佳实践

作者:刘红妍 导读 在自动化测试实践中,测试数据是制造测试场景的必要条件,本文主要讲述了在沟通自动化框架如何分层,数据如何存储,以及基于单元测试pytest下如何执行。并通过实践案例分享,提供数据驱动测试的具体落地方案。 基本概念 数据驱动测试(DDT)是一种方法,其中在数据源的帮助下重复执行相同顺

.NET周报 【6月第1期 2023-06-04】

## 专题 - NanoFramework项目案例 如果有时间,我会在周报中加入一些专题和项目案例的分享,本周就是讨论.NET NanoFramework项目案例的专题,在讨论 NanoFramework 的典型案例之前,让我们先回顾一下 .NET 在嵌入式领域的历史。 2007年,.NET Mic