NGINX未转发认证服务自定义Header至后端服务的问题求助
问题场景
使用NGINX作为网关,客户端请求需先经过认证服务校验,再转发至后端业务服务。当前认证服务返回200状态码时,会在响应中携带自定义Header db_read_time,但该Header无法被NGINX转发到后端服务。查阅NGINX文档得知,upstream_http_db_read_time变量仅指向最后一个被调用的后端服务的响应Header,因此无法获取认证服务返回的该字段,需要实现将认证服务的自定义Header传递给后端服务的方案。
现有代码与配置
认证服务代码(Java)
@RequiredArgsConstructor @RestController public class AuthenticationController { private final JdbcTemplate jdbcTemplate; @GetMapping("/authenticate") public ResponseEntity<String> test(@RequestHeader("Authorization") String authorizationHeader) { return ResponseEntity.ok() .header("db_read_time", "123").body("placeholder"); } }
原NGINX配置
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; log_format custom '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$upstream_http_db_read_time"'; access_log logs/access.log custom; server { listen 80; server_name localhost; location /api/ { auth_request /auth; proxy_pass http://localhost:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header DB-Read-Time $upstream_http_db_read_time; } location = /auth { internal; proxy_pass http://localhost:5001/authenticate; proxy_set_header Content-Type application/x-www-form-urlencoded; proxy_set_header X-Original-URI $request_uri; proxy_set_header Authorization $http_authorization; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
NGINX访问日志
127.0.0.1 - student [04/Oct/2024:17:15:52 +0300] "GET /api/hello HTTP/1.1" 200 27 "-" "curl/8.1.2" "-" "-"
解决方案
核心思路是利用NGINX的auth_request_set指令,在认证请求完成后,将认证服务返回的db_read_timeHeader提取并保存到自定义变量中,随后在转发后端服务时使用该变量设置Header。
修改步骤
- 在
location = /auth块内添加auth_request_set指令,将认证服务返回的db_read_timeHeader值存入自定义变量$auth_db_read_time。 - 在
location /api/块内,将原有的proxy_set_header DB-Read-Time $upstream_http_db_read_time替换为使用自定义变量$auth_db_read_time。
修改后的完整NGINX配置
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; log_format custom '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$auth_db_read_time"'; # 日志中打印自定义变量,便于验证 access_log logs/access.log custom; server { listen 80; server_name localhost; location /api/ { auth_request /auth; proxy_pass http://localhost:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 使用从认证服务提取的自定义变量设置Header proxy_set_header DB-Read-Time $auth_db_read_time; } location = /auth { internal; proxy_pass http://localhost:5001/authenticate; proxy_set_header Content-Type application/x-www-form-urlencoded; proxy_set_header X-Original-URI $request_uri; proxy_set_header Authorization $http_authorization; # 提取认证服务返回的db_read_time到自定义变量 auth_request_set $auth_db_read_time $upstream_http_db_read_time; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
验证方法
- 重启NGINX使配置生效:
nginx -s reload - 发起客户端请求,例如:
curl -H "Authorization: Bearer token" http://localhost/api/hello - 查看后端服务的请求日志,确认是否收到
DB-Read-Time: 123Header - 查看NGINX访问日志,确认
$auth_db_read_time字段已正确打印出123
内容的提问来源于stack exchange,提问作者Yehoraz Levi
相关产品推荐
相关产品推荐

