https反向代理缓存需兼顾一致性与安全性,核心是精准定义缓存键(含authorization/cookie等上下文)、分级设置过期策略、主动清理机制及tls相关隔离。

HTTPS 站点用 Nginx 做反向代理缓存,不能只设个 proxy_cache_valid 就完事。核心矛盾是:既要用户看到最新数据(一致性),又不能让缓存泄露登录态、绕过权限校验或暴露敏感响应(安全性)。关键不在“缓存不缓存”,而在于“缓存谁的、按什么标识、多久失效、谁来清理”。
缓存键必须精准反映 HTTPS 与用户上下文
默认 $scheme$proxy_host$request_uri 在 HTTPS 下虽含 https,但完全忽略请求头和 Cookie 就会出问题。比如后端根据 Authorization 或 X-User-ID 返回不同内容,而缓存键没包含这些字段,A 用户的个人资料就可能被 B 用户命中——这是典型的数据错乱,也是安全风险。
- 带鉴权的接口(如
/api/profile),proxy_cache_key必须加入$http_authorization或$cookie_token;若用 Header,需先在 upstream 前加proxy_set_header Authorization $http_authorization - 静态资源(
/static/,.js,.css)可不带用户字段,但必须保留$scheme和$host,防止 HTTP/HTTPS 混用触发 HSTS 报错或混合内容警告 - 剔除无意义参数,如
_t=123456789,用map预处理$args,避免同一资源生成大量无效缓存项
过期策略要分路径、分状态、分敏感度
HTTPS 站点常承载登录页、订单提交、配置中心等高敏操作,缓存时间不能一刀切。应按业务语义分级控制:
- 公开静态资源(
/logo.png,/css/app.a1b2c3.css):设长周期,如proxy_cache_valid 200 365d,配合Cache-Control: public, immutable - 带用户态的动态接口(
/api/user):建议proxy_cache_valid 200 5m,并启用proxy_ignore_headers Cache-Control,再由后端返回Cache-Control: private, max-age=300,让 Nginx 尊重该语义 - 高敏感操作(
/api/order/submit,/auth/logout):禁用缓存,显式配置proxy_no_cache $http_pragma $http_authorization和proxy_cache_bypass $http_pragma $http_authorization
主动清理是保障一致性的必要手段
等缓存自然过期无法应对突发变更,比如商品价格更新、用户权限回收。Nginx 自身不监听业务事件,需外部触发:
- 启用
ngx_cache_purge模块,开放/purge/xxx接口,由发布系统调用清理指定路径,例如:location /purge { allow 127.0.0.1; deny all; proxy_cache_purge mycache $host$request_uri$is_args$args; } - 对关键页面(如用户首页),采用缓存键版本化:在
proxy_cache_key中嵌入变量$cache_version,发布时更新该变量值,旧缓存自动失效 - 配合
proxy_cache_revalidate on和proxy_cache_background_update on,让 Nginx 在后台异步刷新即将过期的缓存,避免用户直面回源延迟
加密相关缓存需额外隔离与限制
HTTPS 不仅是传输加密,还涉及证书验证、会话复用、OCSP 响应等状态缓存。这些内容不能混入通用缓存区,也不能被客户端或中间代理误用:
- 禁止缓存任何含
Set-Cookie、WWW-Authenticate、Authorization的响应,通过proxy_hide_header Set-Cookie和proxy_ignore_headers Set-Cookie双重拦截 - TLS 层的会话票证(Session Ticket)由浏览器和服务器协商管理,Nginx 不参与,但需确保
ssl_session_cache配置合理(如shared:SSL:10m),避免重复握手开销 - 若使用 OCSP Stapling,注意
ssl_stapling_verify on和resolver设置,防止因 OCSP 响应缓存异常导致 TLS 握手失败(类似火狐中sec_error_ocsp_invalid错误)











