Nginx做请求转发时丢失请求头的问题
背景
今天使用docker-compose编排容器部署前后端分离的项目,nginx+springboot+mysql+redis。
部署完发现后端服务接口一直鉴权失败,看了代码和日志,确认时没有获取到鉴权用的请求头"xxx_token",但是其他请求头正常。
遂查看浏览器请求,发现是有这个Request Header的。也是就headeruser_id达到后端微服务时没有了。
那么代码没有改动,怎么平白无故会丢失请求头?
想到本地和线上唯一的区别就是多了nginx代理转发,于是用搜索引擎查之。
有人提过问题 lost custom http header when using nginx+passenger
Ask
原因
Nginx会自动忽略含有_
的请求头
解决办法
修改请求头名称
既然nginx对下划线不支持,那没关系,不用下划线就是了。比如原来”app_version”改成”app-version”就可以了。(难怪一般header的name都是’-‘来拼接的,比如”User-Agent”)
修改nginx配置
查阅官方文档,与此问题相关的配置项有两个
ignore_invalid_headers on|off 原文
语法:
ignore_invalid_headers on | off;
默认:
ignore_invalid_headers on;
级别:
http
, server
控制是否应忽略名称无效的请求头。有效名称由英文、数字、连字符-
和可选的下划线_
组成(由underscores_in_headers 指令控制)。
underscores_in_headers on|off 原文
语法:
underscores_in_headers on | off
;
默认:
underscores_in_headers off;
级别:
http
, server
在客户端的请求头中启用或禁用下划线。禁止使用下划线时,名称中包含下划线的请求标头字段将被视为无效,并受ignore_invalid_headers指令的约束。
以上两个如果配置是在服务器级别,则仅当该服务器为默认服务器时才使用其值。指定的值也适用于在相同地址和端口上侦听的所有虚拟服务器。
nginx默认request的header的那么中包含’_’时,会自动忽略掉。
解决方法是:在nginx里的nginx.conf配置文件中的http部分中添加如下配置:
underscores_in_headers on; # 默认是off