$upstream_cookie_*变量用于读取上游响应Set-Cookie头中指定名称的Cookie值,仅在proxy_pass后且响应含该Cookie时有效,自动URL解码,区分大小写,可用于日志记录或条件响应。

在 Nginx 中,$upstream_cookie_* 变量用于捕获上游(后端)响应头中 Set-Cookie 指令所设置的 Cookie 值。若后端动态下发鉴权令牌(如 auth_token=xxx; Path=/; HttpOnly; Secure),可通过该变量实时感知其变更,用于日志记录、路由决策或安全审计。
理解 $upstream_cookie_* 的行为边界
该变量仅在 proxy_pass 后且上游响应含 Set-Cookie 时才有效;它提取的是 Cookie 名称解码后的值(如 Set-Cookie: auth_token=abc%3D123; Path=/ → $upstream_cookie_auth_token 值为 abc=123)。注意:
- 变量名需与 Cookie 名完全匹配(区分大小写),下划线自动转为中划线,但建议后端用下划线命名以兼容
- 若同一响应设多个同名 Cookie(如重定向链中多次 Set-Cookie),Nginx 默认取第一个(按 RFC 规范,后续应被忽略)
- 该变量不可写,仅读取;不能用于
proxy_set_header直接透传,需配合map或add_header使用
记录令牌变更到 access_log
在 log_format 中直接引用变量,实现每条请求日志附带本次上游返回的令牌值(便于比对是否刷新):
log_format upstream_token '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream_token="$upstream_cookie_auth_token"';
再在 server 或 location 中启用该格式:
access_log /var/log/nginx/access_with_token.log upstream_token;
日志示例:
192.168.1.100 - - [10/Jul/2024:14:22:33 +0800] "GET /api/user HTTP/1.1" 200 124 "-" "curl/7.68" upstream_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
基于令牌变化做条件响应或跳转
使用 map 将令牌值映射为标记,再结合 if 或 error_page 实现轻量级响应控制:
map $upstream_cookie_auth_token $token_changed {
default "";
"~^eyJh.*" "yes"; # 匹配 JWT 格式开头(示意)
}
<p>server {
location /api/ {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
proxy_cookie_path / "/; Secure; HttpOnly";</p><pre class="brush:php;toolbar:false;"> # 若检测到新令牌,添加响应头供前端感知
add_header X-Auth-Token-Changed $token_changed;
# 或触发内部重写(如需强制前端刷新本地缓存)
if ($token_changed = "yes") {
add_header X-Refresh-Hint "token_updated";
}
}}
注意事项与常见问题
实际部署中需留意:
- 确保
proxy_buffering off或足够大的proxy_buffer_size,否则大 Cookie 可能被截断,导致$upstream_cookie_*为空 - 若后端通过多层代理(如 LB → API 网关 → 业务服务),Nginx 需配置
proxy_pass_request_headers on并确认中间层未剥离Set-Cookie - Cookie 值含特殊字符(如空格、分号)时,Nginx 自动解码,但若后端未正确 URL 编码,可能解析失败——建议后端统一 base64url 或 hex 编码令牌值
- 该机制无法捕获客户端主动删除 Cookie 后的“丢失”状态,仅反映上游本次响应的下发动作











