nginx默认不透传x-前缀及含下划线的自定义请求头,需配置underscores_in_headers on和proxy_set_header x-user-token $http_x_user_token;再通过日志逐层排查是否接收、转发及后端识别。

后端鉴权失败,但前端确实传了自定义头(如 X-User-Token),问题大概率出在 Nginx 没把头转发过去——这不是 bug,是 Nginx 默认行为。排查要从“Nginx 是否收到、是否透传、后端是否识别”三层入手。
确认请求头是否被 Nginx 接收
先看 Nginx 能不能看到原始请求头:
- 临时开启详细日志,在
log_format中加入$http_x_user_token(注意小写、下划线); - 重启 Nginx 后触发一次请求,查
access.log对应行:如果该字段为空或缺失,说明前端根本没发过来,或浏览器/CDN 已过滤; - 若字段有值,证明 Nginx 收到了,问题在转发环节。
检查 Nginx 是否主动丢弃了自定义头
Nginx 默认不透传带 X- 前缀的自定义头,也不支持含下划线的头(如 X_User_Token):
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 确保配置中显式写了:
proxy_set_header X-User-Token $http_x_user_token;; - 如果头名含下划线(如
X_User_Token),必须在http或server块顶部加:underscores_in_headers on;; - 避免用
add_header替代proxy_set_header,前者只影响响应头,不作用于转发。
验证后端是否真正收到该头
绕过前端干扰,直接让后端打印所有请求头:
- Spring Boot 可加日志:
request.getHeaders().forEach((k,v) -> log.info("Header: {} = {}", k, v));; - Node.js 可打印
req.headers; - 若日志里完全不见
x-user-token(注意全小写),说明 Nginx 没转发成功; - 若存在但值为空,可能是前端未正确设置(如未在
fetch的headers中传入)。
排除常见干扰项
有些配置会静默覆盖或阻断头传递:
- 检查是否误启用了
mod_security或 WAF 规则,拦截了非常规头; - 确认没有重复定义
proxy_set_header,后定义的会覆盖前一个; - 若用了
proxy_pass到 HTTPS 后端,注意部分老版本 Nginx 会过滤某些头,建议升级到 1.19+; - 测试时用
curl -H "X-User-Token: abc123" http://your-domain.com/api直接验证,排除浏览器 CORS 或缓存干扰。










