记一次请求头header丢失问题排查实录

前言

前端小王需要调用兄弟部门老张的后端接口,老张提供的接口,需要token鉴权才能调用成功。当小王按约定携带token调用老张的接口时,起先因为跨域问题,导致前端小王没法成功请求老张的接口。于是小王就跟老张说,能不能他那边配置下允许跨域。但小王是一个很有原则的人,他说这个接口是要给N个部门调用的,不可能给这些调用部门都配置允许跨域,不然口子一旦开了,后面就没完没了,他让小王自己想办法解决跨域。后面小王就把事情向上反馈,小王的领导就跟小王说,我们自己搭个反向代理,通过反向代理解决跨域问题。本文的素材就是来源于此次搭建反向代理后,发生的故事

故事延续

因为前端本来就是基于nginx进行代理,因此小王就直接把老张的接口地址,配置在nginx上。配好后小王就找老张再一次联调,这次跨域的问题是解决了,但是接口返回”系统出现异常,请联系管理员”,小王就问让老张排查一下是啥情况,老张看了日志说,是token空了,就问小王是不是token没传,小王信誓旦旦说传了,并把传token的截图丢给老张。

到这事情就很诡异了,小王明明按老张的接口要求,传了token,但为啥老张没接收到token,后边小王就说老张的接口有bug,老张的第一反应是,不可能,这个接口已经提供给好几个系统使用了,他们都没问题。小王就说他们使用没问题,不能代表你接口就是没bug,我这边都按你要求的格式传了,你却没收到,那肯定是你那边问题了。

因为小王和老张都觉得自己请求或者调用没问题,就找了在公司很有威望的程序员老黄来评判,老黄毕竟没参与过小王或者老张的业务项目,他就没从业务入口,而是从端到端的请求入手,他先分析一下请求链路,其次看了一下请求参数,其中token的header参数的key,引起了他注意。这个token的header参数key,为auth_token,于是他就让小王在nginx 的http或者server块配置如下参数

underscores_in_headers on

然后再试下。这次接口很丝滑的通了,小王和老子对老黄的敬仰之情又多了一分

复盘

1、为什么加了underscores_in_headers on,接口就好使了?

我们直接贴官网的说明

他的中文大意是当客户端请求头的字段中带有下划线,nginx默认会将该字段标识为无效字段
既然是无效了,当然token就空了。详细可以看官方链接
http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers

其实还有另外一种解法就是大家约定好,不要用下划线,比如将auth_token,改为auth-token.。不过如果涉及到多方系统已经使用了下划线的情况,此时要推进改动,可能就要涉及很多沟通成本了

总结

本文虽然说是讲请求头header丢失的问题,但更多是复现一个开发联调时候的场景,很多时候我们都会觉得我们开发出来的东西没问题,会带有一种迷之自信,其次我文章故意将”系统出现异常,请联系管理员”这个返回值抛出来,这个返回值如果面向对象是业务方,大体是问题不大,但如果是面向群体是开发,无形中就增加沟通成本。很多时候我们大部分的联调时间,其实是耗费在沟通上。

最后补充一下附录跨域和允许下划线访问的内容就当做一个彩蛋,本文的真实场景,其实是通过nginx-ingress来做7层转发

附录

 kubectl.kubernetes.io/last-applied-configuration: |-
      if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728008;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,PATCH,OPTIONS';
        return 200;
       }
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/cors-allow-credentials: 'true'
    nginx.ingress.kubernetes.io/cors-allow-headers: >-
      DNT,x-app-id,x-tenant-id,x-user-id,Authorization,Accept,Origin,Keep-Alive,User-Agent,access-control-allow-origin,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,systemId,Cookie,x-agent-type,x-noauth,isrefreshtoken,auth_token
    nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
    nginx.ingress.kubernetes.io/cors-allow-origin: '*'
    nginx.ingress.kubernetes.io/enable-cors: 'true'
    nginx.ingress.kubernetes.io/proxy-body-size: 300m
    nginx.ingress.kubernetes.io/server-snippet: |
      underscores_in_headers on;
    nginx.ingress.kubernetes.io/ssl-redirect: 'false'

其中

   kubectl.kubernetes.io/last-applied-configuration: |-
      if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728008;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,PATCH,OPTIONS';
        return 200;
       }
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/cors-allow-credentials: 'true'
    nginx.ingress.kubernetes.io/cors-allow-headers: >-
      DNT,x-app-id,x-tenant-id,x-user-id,Authorization,Accept,Origin,Keep-Alive,User-Agent,access-control-allow-origin,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,systemId,Cookie,x-agent-type,x-noauth,isrefreshtoken,auth_token
    nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
    nginx.ingress.kubernetes.io/cors-allow-origin: '*'
    nginx.ingress.kubernetes.io/enable-cors: 'true'

是允许跨域请求的部分

其中

 nginx.ingress.kubernetes.io/server-snippet: |
      underscores_in_headers on;

是允许请求头包含下划线的部分

当然还可以通过在ingress-nginx-controller的configmap里添加

enable-underscores-in-headers: "true" 

开启全局配置允许请求头包含下划线

示例配置

apiVersion: v1
data:
  allow-snippet-annotations: "true"
  enable-underscores-in-headers: "true"
  use-forwarded-headers: "true"
kind: ConfigMap
....省略其他

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/143928.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【科研新手指南4】ChatGPT的prompt技巧 心得

ChatGPT的prompt心得 写在最前面chatgpt咒语1(感觉最好用的竟然是这个,简单方便快捷,不需要多轮对话)chatgpt思维链2(复杂任务更适用,简单任务把他弄复杂了)机理chatgpt完整咒语1(感…

python 文本纠错库pycorrector的使用(API变更,许多介绍文章已不可用)

pycorrector是一个nice的中文检测库,在最新的版本API变更,导致许多之前的介绍文章不可用。 现将新API粘贴如下。

1、 图像和像素

像素我们不陌生,图像我们更不陌生。 学习计算机视觉,我觉得第一步就是要了解我们要处理的对象,就像上一篇说到的,计算机视觉任务中,图像(像素)是原材料,算法是菜谱。 了解了图像的特征,才可以更好的完成更多图像处理任务,比如对一张图片进行分类,或者对一张图片画…

【数据仓库】数仓分层方法详解与层次调用规范

文章目录 一. 数仓分层的意义1. 清晰数据结构。2. 减少重复开发3. 方便数据血缘追踪4. 把复杂问题简单化5. 屏蔽原始数据的异常6. 数据仓库的可维护性 二. 如何进行数仓分层?1. ODS层2. DW层2.1. DW层分类2.2. DWD层2.3. DWS 3. ADS层 4、层次调用规范 一. 数仓分层…

如何使用Echarts

以umi为例 首先是下载两个插件(echarts和echarts-for-react) npm npm install --save echarts-for-react npm install echarts yarn yarn add echarts-for-react yarn add echarts 接下来是在tsx或jsx中引入使用 import ReactEcharts from "echa…

selenium报错:没有打开网页或selenium.common.exceptions.NoSuchDriverException

文章目录 问题解决方法 问题 当selenium的环境配置没有问题,但在使用selenium访问浏览器时并没有打开网页,或者出现selenium.common.exceptions.NoSuchDriverException报错信息(如下图所示)。 以上问题可能的原因是没有配置chrom…

Alter database open fails with ORA-00600 kcratr_nab_less_than_odr

Alter database open fails with ORA-00600 kcratr_nab_less_than_odr (Doc ID 1296264.1)​编辑To Bottom APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0.1 to 11.2.0.1 [Release 11.2] Oracle Database - Enterprise Edition - Version 12.1.0.1 to …

保护多个子域名——通配符证书

在当今的互联网世界中,许多组织和企业拥有复杂的网站结构,包含许多不同的子域名。而为每个子域名单独购买和管理SSL证书可能会相当繁琐。解决这一问题的理想选择就是通配符证书。 一、什么是通配符SSL证书? 通配符SSL证书又叫泛域名证书&am…

智能电网阻抗模拟的应用背景

智能电网阻抗模拟是一种利用计算机模拟技术,对智能电网中各种电力设备和电力系统的阻抗特性进行模拟和分析的方法。智能电网是指通过信息通信技术和先进的控制策略,实现电力系统高效、安全、可靠和可持续运行的电网。在智能电网中,各种电力设…

Spring全家桶源码解析--2.4 Spring bean 的依赖注入--@Resource

文章目录 前言一、Resource 作用:二、Resource 源码实现:2.1 Resource 注入点获取:2.2 Resource 对注入点依赖注入: 三、 总结 前言 Spring 中不仅可以使用Spring 包中的Autowired 还可以使用java 层面提供的Resource 进行依赖注…

阿里云学生及教师优惠活动,学生用户享3折购买优惠,教师享5折购买优惠

阿里云推出高校计划“云工开物”,助力高校师生云上“创世界”,学生用户享300元优惠券和3折购买优惠,教师享5折购买优惠。“云工开物”将倾力支持高校教师云上科研提速,取得有世界级影响力的成果;助力高校学生在云上探索…

无代码:解决非程序员的开发难题

最近,有个小型企业的负责人找上我,说他公司需要一个内部管理系统,来提高工作和协作效率,但他没有编程经验,也不打算花费大量时间和金钱雇佣专业的开发团队,他问我有没有什么解决方案。 针对这个问题&#…

FusionDiff:第一个基于扩散模型实现的多聚焦图像融合的论文

文章目录 1. 论文介绍2. 研究动机3. 模型结构3.1 网络架构3.2 前向扩散过程3.3 逆向扩散过程3.4 训练和推理过程 4. 小样本学习4. 实验结果 1. 论文介绍 题目:FusionDiff: Multi-focus image fusion using denoising diffusion probabilistic models 作者&#xf…

ARPG----C++学习记录05 Section9 动画蓝图,腿部ik

这节课比较难懂,我也不是很理解 动画蓝图 新建一个动画蓝图。首先新建一个人物蓝图的变量用来获取人物的属性,使用第一行蓝图来初始化,当人物为Echo时获取它的movement组件,存为变量。然后动画的每一帧都从movement组件里拿出xy的速度用作后边…

软件外包的需求整理技巧

在软件开发中,整理需求是确保项目成功的重要步骤之一。以下是一些整理需求的技巧,这些技巧有助于确保需求的清晰性、完整性和可行性,为项目的成功打下坚实的基础。北京木奇移动技术有限公司,专业的软件外包开发公司,欢…

有什么方法可以改善CRM实施投资回报?

数据统计显示,几乎70%以上CRM客户管理系统项目的投资回报是负数。这意味着超过半数的CRM项目的结果是失败的。那么我们有什么方法可以改善CRM实施投资回报吗?当然有,下面我们就来说一说。 如何改善CRM实施投资回报 首先,您选择的…

新品 | 飞凌嵌入式FCU2601工商业储能EMS能量控制单元发布

FCU2601嵌入式控制单元是飞凌嵌入式为锂电池储能行业设计的EMS能量控制单元产品,设计兼具高性能,多接口,低功耗,广泛满足各类储能系统的本地能源管理应用需求。 FCU2601嵌入式控制单元综合考虑到了储能行业不同场景的差异化需求&…

RT1170的ITM SWO配置,实现printf输出及PC指针的采样分析

最近公司准备启动一个新的项目,使用NXP的MIMXRT1170芯片作为主控,在熟悉芯片的过程中发现RT1176具备ITM和SWO功能模块,于是针对之前项目中因工程庞大导致调试困难的问题,决定使用SWO输出调试信息,这样既可以节省硬件的…

Python生成随机数插件Faker的用法

目录 引言 一、Faker库的安装 二、Faker库的基本用法 1、导入Faker类 2、创建Faker对象 3、使用Faker对象生成随机数据 三、Faker库的高级用法 1、自定义数据生成规则 2、使用子模块进行特定领域的数据生成 3、与其他库结合使用 四、Faker库的应用场景 1、单元测试…

虚拟化加密磁盘密钥设置方案浅析 — TKS1

虚拟化加密磁盘密钥设置方案浅析 前言密钥设置方案密钥管理服务-KMS密钥设置方案-TKS1 两级加密设计弱熵密码派生密钥切分存储 前言 虚拟化组件可以使用多种加密算法对虚拟机磁盘的原始内容进行加解密,比如AES、RSA、SM2/SM3/SM4等,用户写入的数据经过加…