nginx 默认不缓存带 authorization 请求头的请求,需显式配置 proxy_cache_key 包含 $http_authorization 或其哈希值,并配合 proxy_ignore_headers、proxy_cache_bypass 等指令实现安全缓存。

带 Authorization 请求头的请求,默认完全不进 Nginx 缓存流程——这不是配置遗漏,而是 Nginx 的安全硬限制。它会直接跳过缓存查找和存储,哪怕你已开启 proxy_cache 并设置了 proxy_cache_valid。想让它缓存,必须主动“放行”,同时确保不会导致用户数据混用或泄露。
明确放行:让 Authorization 参与缓存键计算
默认缓存键(如 $scheme$request_method$host$request_uri)不含认证信息,所有带 Authorization 的请求都算作“同一资源”,极易越权。必须显式引入该头:
- 使用
$http_authorization变量(注意全小写、无横线),例如:proxy_cache_key "$scheme$request_method$host$request_uri$http_authorization"; - 更稳妥的做法是哈希化,避免长 token 导致缓存键过长或含非法字符:
proxy_cache_key "$scheme$request_method$host$request_uri$sha1($http_authorization)"; - 若后端依赖其他认证头(如
X-Api-Key),需先启用underscores_in_headers on;,再加入对应变量(如$http_x_api_key)
清除缓存禁令:忽略后端返回的禁止缓存指令
即使你改了 key,Nginx 仍可能因后端响应头中的 Cache-Control: private 或 no-store 而拒绝缓存。这时需主动“忽略”:
- 添加
proxy_ignore_headers Cache-Control Expires Set-Cookie; - 注意:
proxy_ignore_headers不改变响应头本身,只影响 Nginx 的缓存决策逻辑 - 前提是后端响应确实允许共享缓存(如返回
Cache-Control: public, max-age=60),否则仅靠 Nginx 配置无法绕过语义限制
防止误共享:区分认证态与未认证态请求
游客访问 /api/profile 和登录用户访问同一路径,内容完全不同。不能共用一个缓存条目:
- 用
proxy_cache_bypass $http_authorization;:当存在 Authorization 头时,强制不读缓存(回源),避免游客命中已认证用户的旧缓存 - 或用
map更精细控制:map $http_authorization $skip_cache { "" 1; default 0; }
再配proxy_cache_bypass $skip_cache;,实现“有认证才可缓存” - 搭配
proxy_no_cache $http_authorization;可进一步禁止将带认证的响应写入缓存(适合只读网关场景)
验证是否真正生效
配完不等于跑通,必须实测确认:
- 加响应头便于观察:
add_header X-Cache-Status $upstream_cache_status; - 用 curl 发起两次相同 Authorization 的请求,检查第二次是否返回
X-Cache-Status: HIT,且Age头递增 - 换另一个 token 再请求,确认返回
X-Cache-Status: MISS或BYP,且内容与前次不同 - 检查缓存目录下是否生成了多个以不同 hash 开头的文件,而非单一文件被反复覆盖











