Nginx 中 proxy_pass 转发时需用 proxy_set_header 注入签名头,静态写死适用于可信内部调用,透传需校验来源可信性,动态签名推荐 auth_request 模块配合外部服务生成并注入变量,同时须设置 Host、X-Forwarded-Proto、X-Real-IP 等基础头保证上下文完整。

在 Nginx 中让 proxy_pass 转发请求时携带统一的签名验证头,关键不是靠 proxy_pass 本身,而是用 proxy_set_header 显式注入。但要注意:签名头必须是可信、可控、不被客户端随意篡改的——否则就失去验证意义。常见做法是服务端生成(如内部调用)或由前置鉴权模块(如 auth_request)注入。
用 proxy_set_header 静态注入固定签名头
适用于内部可信服务调用,比如管理后台直连后端 API,Nginx 统一加签名:
- 直接写死值,简单可靠:
proxy_set_header X-Api-Sign "v1:abc1234567890"; - 值中含空格或特殊字符时,建议用单引号包裹:
proxy_set_header X-Api-Sign 'v1:sha256=xyz+base64'; - 注意:该方式无法动态计算签名(如拼接时间戳 + body hash),纯 Nginx 不支持 HMAC 或 Base64 编码
透传可信来源的签名头(如 CDN 或网关已签好)
如果上游(如 CDN、API 网关)已在请求中加了 X-Api-Sign,且你信任该链路,可选择性透传:
- 只在来源可信时转发(配合
$http_origin或$remote_addr判断):if ($remote_addr ~ ^(10\.0\.10\.|192\.168\.1\.)$) { proxy_set_header X-Api-Sign $http_x_api_sign; } - 更推荐用
map预处理,避免if的局限:map $http_x_api_sign $pass_sign { "" ""; default $http_x_api_sign; }
然后:proxy_set_header X-Api-Sign $pass_sign;
结合 auth_request 动态注入用户级签名上下文
真正带验证逻辑的场景(如校验 URL 参数签名),需借助 auth_request 模块,由外部服务返回变量再注入:
- 验证服务(如 Node.js)校验通过后,返回自定义响应头,例如:
X-Auth-User-ID: user123X-Auth-Timestamp: 1715500000 - Nginx 中捕获并透传:
auth_request_set $auth_user $upstream_http_x_auth_user_id;<br>auth_request_set $auth_time $upstream_http_x_auth_timestamp;<br>proxy_set_header X-User-ID $auth_user;<br>proxy_set_header X-Request-Time $auth_time;
- 后端可用这些字段组合校验签名,避免重复解析原始参数
必须配套的基础头设置
签名头要生效,还需保证后端能拿到真实请求上下文:
- 保留原始 Host,防止后端重定向出错:
proxy_set_header Host $host; - 标明协议类型(尤其 HTTPS → HTTP 内部转发时):
proxy_set_header X-Forwarded-Proto $scheme; - 传递真实客户端 IP,用于限流或风控关联:
proxy_set_header X-Real-IP $remote_addr;<br>proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


















