在 nginx 中,若缓存键(proxy_cache_key)包含 cookie,nginx 会默认将每个不同的 cookie 组合视为独立的缓存对象。要实现会话隔离,核心做法是确保缓存键中包含能唯一标识用户会话的字段(如 `cookie` 变量),这样不同用户的请求就会生成不同的缓存文件,互不干扰。

如何配置 proxy_cache_key 以区分不同 Cookie
要隔离用户会话,必须在 proxy_cache_key 指令中显式加入 $http_cookie 变量。Nginx 会将该变量的值作为缓存文件名的一部分,从而为每个唯一的 Cookie 组合创建独立的缓存条目。

server {
listen 80;
server_name example.com;
# 定义缓存路径和参数
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /api/ {
# 关键配置:将 Cookie 纳入缓存键
proxy_cache_key "$scheme$request_method$host$request_uri$http_cookie";
proxy_pass http://backend_server;
proxy_cache my_cache;
# 设置缓存过期时间
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}
上述配置中,$http_cookie 包含了客户端发送的所有 Cookie。当用户 A 和用户 B 访问同一 URL 时,由于他们的 Session ID 或 Token 不同,生成的缓存键也不同,因此 Nginx 会分别缓存两份内容,实现了严格的会话隔离。
如何处理动态内容与静态资源的混合场景
在实际应用中,通常只有部分接口需要基于 Cookie 进行缓存隔离,而静态资源(如图片、CSS)则不需要。可以通过 map 指令或条件判断来动态调整缓存策略,避免对静态资源产生过多的缓存碎片。

# 在 http 块中定义 map
map $request_uri $cache_key_suffix {
default "";
~^/api/ "$http_cookie";
}
server {
listen 80;
server_name example.com;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /api/ {
# 使用动态生成的缓存键
proxy_cache_key "$scheme$request_method$host$request_uri$cache_key_suffix";
proxy_pass http://backend_server;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
}
location ~* \.(jpg|jpeg|png|gif|css|js)$ {
# 静态资源不使用 Cookie 作为缓存键,统一缓存
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_pass http://static_backend;
proxy_cache static_cache;
proxy_cache_valid 200 1d;
}
}
通过这种配置,/api/ 开头的请求会根据 $http_cookie 生成不同的缓存键,实现会话隔离;而静态资源请求则忽略 Cookie,共享同一个缓存键,提高了缓存命中率并减少了磁盘占用。
当 Cookie 为空或包含敏感信息时缓存行为如何
如果客户端未发送 Cookie,$http_cookie 的值为空字符串,此时所有无 Cookie 的请求将共享同一个缓存键,可能导致数据泄露。此外,若 Cookie 中包含敏感信息(如密码),直接将其放入缓存键可能带来安全风险。建议对 Cookie 进行过滤或使用哈希处理。
# 在 http 块中使用 map 过滤敏感 Cookie
map $http_cookie $safe_cookie {
default "";
~*session_id=([^;]+) $1;
}
server {
listen 80;
server_name example.com;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /api/ {
# 仅使用 session_id 作为缓存键的一部分,忽略其他 Cookie
proxy_cache_key "$scheme$request_method$host$request_uri$safe_cookie";
proxy_pass http://backend_server;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
}
}
此配置通过正则匹配提取 session_id,并将其用于缓存键。这样既实现了会话隔离,又避免了其他非关键 Cookie 导致的缓存碎片化,同时降低了敏感信息暴露的风险。若 session_id 不存在,则缓存键简化为基础 URL,适用于公开内容。











