核心是隔离后端应用的session cookie:①用proxy_cookie_path重写路径(如/app1/)并配置后端sessioncookiepath;②用proxy_cookie_domain统一修正domain为.example.com;③为各应用设不同sessioncookiename(如app1_jsessionid);④禁用ip_hash/session复制,改用redis独立命名空间。

核心是让每个后端应用的 Session Cookie 互不干扰,避免路径、域名或名称重叠导致浏览器错误携带。
隔离 Cookie 的路径(最关键)
当 Nginx 同时代理 /app1 和 /app2 两个 Tomcat 应用时,若后端都返回 Set-Cookie: JSESSIONID=xxx; Path=/,浏览器会在访问任一路径时都带上该 Cookie,造成交叉污染。
- 在对应 location 块中显式重写 Cookie 路径:
proxy_cookie_path / /app1/;(用于 app1)proxy_cookie_path / /app2/;(用于 app2) - 确保后端应用自身也配置为生成带路径的 Cookie,例如 Tomcat 的
context.xml中设置sessionCookiePath="/app1" - 路径必须以
/开头且结尾一致,否则浏览器可能不发送
区分 Cookie 的域名与作用域
如果多个应用共用同一主域名(如 example.com),但部署在不同子路径下,需防止内网或测试环境的 Domain 设置泄露到公网。
- 用
proxy_cookie_domain统一修正:例如后端返回Domain=192.168.1.10,应映射为proxy_cookie_domain 192.168.1.10 .example.com; - 避免后端硬编码
Domain,优先由 Nginx 统一控制;使用带点前缀的.example.com表示通配所有子域 - 若应用完全独立(如
app1.example.com和app2.example.com),则天然隔离,无需额外干预
避免 Session ID 名称冲突
多个 Java 应用默认都用 JSESSIONID,即使路径隔离,若某应用未严格校验路径,仍可能误读其他应用的 ID。
- 为不同应用配置不同的 Session Cookie 名称:Tomcat 可通过
context.xml设置sessionCookieName="APP1_JSESSIONID" - Nginx 不需要为此做特殊配置,但需确保
proxy_cookie_path和proxy_cookie_domain仍按新名称生效(它们对名称无感,只处理值和属性) - Spring Boot 项目可在
application.yml中设server.servlet.session.cookie.name: APP1_SESSION_ID
补充:不推荐依赖 ip_hash 或 session 复制
ip_hash 无法解决多应用共存问题,它只影响请求分发目标,不解决 Cookie 冲突;session 复制(如 Tomcat 集群)会让各节点互相广播全部 Session,反而加剧污染风险,且扩展性差。
- 真正解耦的方式是让每个应用拥有独立的 Session 存储空间(如 Redis 中不同 database 或不同 key 前缀)
- 若必须共用 Redis,后端需为每个应用设置唯一
redisNamespace,例如spring.session.redis.namespace=app1:sessions - Nginx 层只需专注 Cookie 的路径、域、安全属性等转发控制,不参与 Session 数据逻辑











