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

前言

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

故事延续

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

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

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

javascript 复制代码
underscores_in_headers on

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

复盘

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

我们直接贴官网的说明 他的中文大意是当客户端请求头的字段中带有下划线,nginx默认会将该字段标识为无效字段 既然是无效了,当然token就空了。详细可以看官方链接 nginx.org/en/docs/htt...

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

总结

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

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

附录

yaml 复制代码
 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'

其中

yaml 复制代码
   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'

是允许跨域请求的部分

其中

yaml 复制代码
 nginx.ingress.kubernetes.io/server-snippet: |
      underscores_in_headers on;

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

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

yaml 复制代码
enable-underscores-in-headers: "true" 

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

示例配置

yaml 复制代码
apiVersion: v1
data:
  allow-snippet-annotations: "true"
  enable-underscores-in-headers: "true"
  use-forwarded-headers: "true"
kind: ConfigMap
....省略其他
相关推荐
xujiangyan_19 小时前
nginx的反向代理和负载均衡
服务器·网络·nginx
viqecel1 天前
网站改版html页面 NGINX 借用伪静态和PHP脚本 实现301重定向跳转
nginx·php·nginx重定向·301重定向·html页面重定向
硪就是硪2 天前
内网环境将nginx的http改完https访问
nginx·http·https
ak啊2 天前
Nginx 安全加固详细配置指南
nginx
沐土Arvin2 天前
Nginx 核心配置详解与性能优化最佳实践
运维·开发语言·前端·nginx·性能优化
haoranyyy3 天前
mac环境中Nginx安装使用 反向代理
linux·服务器·nginx
ak啊3 天前
Nginx 高级缓存配置与优化
nginx
再学一丢丢3 天前
Keepalived+LVS+nginx高可用架构
nginx·架构·lvs
xujiangyan_3 天前
nginx的自动跳转https
服务器·nginx·https
tingting01194 天前
k8s 1.30 安装ingress-nginx
nginx·容器·kubernetes