web.xml 中 http-only 必须全小写、置于 内且该标签需嵌套在 中,值仅支持 true/false;它仅作用于容器自动创建的 jsessionid cookie,不生效于手动添加的 cookie。

web.xml 里 http-only 是怎么配的?
不是写成 HttpOnly,也不是加引号或大写拼写,必须是全小写 http-only,且只能出现在 <cookie-config></cookie-config> 内部。写错大小写或放错位置(比如塞进 <session-config></session-config> 外层)会导致配置完全不生效,容器连解析都不解析。
常见错误现象:Set-Cookie 响应头里始终没出现 HttpOnly 标志,即使 web.xml 看起来“写了”。
-
<cookie-config></cookie-config>必须嵌套在<session-config></session-config>里面,不能平级 - 值只能是
true或false,不能写on/yes/1 - Tomcat 7+、Jetty 9+、WebLogic 12c+ 支持;老版本如 Tomcat 6 不识别该标签
为什么 http-only 设为 true 后 JS 还能读到 session ID?
根本原因:这个配置只影响容器自动创建的 JSESSIONID Cookie,不影响你代码里手动用 response.addCookie() 新建的 Cookie。如果项目里有自定义登录态管理、或者用了前端存储 token 的方案,http-only 对那些完全没作用。
另外,如果应用同时存在多个 Cookie(比如一个存用户信息、一个存权限),只有 JSESSIONID 那个受控;其他 Cookie 必须单独调用 cookie.setHttpOnly(true) 设置。
- 检查浏览器开发者工具的
Application → Cookies,确认HttpOnly列是否打钩 - 用
curl -I http://localhost:8080/xxx看响应头里Set-Cookie:是否带HttpOnly - Spring Boot 用户注意:若用了
spring-session,默认会覆盖 web.xml 配置,得改SessionRepositoryFilter行为
cookie-config 里还有哪些关键项和 http-only 强相关?
http-only 不是孤立参数,它和 secure、max-age、path 共同决定 Cookie 的安全边界。漏配 secure 在 HTTPS 环境下会让 http-only 形同虚设——攻击者仍可通过 HTTP 中间人劫持拿到 Cookie。
-
<secure>true</secure>:强制 Cookie 只走 HTTPS,和http-only是“安全组合”,缺一不可 -
<http-only>true</http-only>+<secure>false</secure>= 明文传输 + 禁 JS 访问 → 白忙活 -
<path>/</path>若设成/admin,可能导致部分子路径无法携带 Cookie,间接让 session 失效
Tomcat 8.5+ 默认已经开启 http-only,为什么还要配 web.xml?
因为 Tomcat 的默认行为只对新部署的应用生效,且依赖 context.xml 里的 useHttpOnly(默认 true)。但如果你的应用打了 WAR 包丢进别人运维的旧环境,或者用了非标准部署方式(比如嵌入式 Tomcat),web.xml 配置才是最直接、最可控的兜底手段。
更关键的是:web.xml 配置优先级高于 Tomcat 全局设置,能覆盖掉中间件层面可能存在的误配。
- 验证方式:删掉 web.xml 里的
cookie-config,重启后 curl 看响应头是否还带HttpOnly - 某些云平台(如阿里云 EDAS)会强制重写 session 配置,此时 web.xml 反而会被忽略,得查平台文档
- 微服务架构下,网关层(如 Spring Cloud Gateway)可能剥离或重写 Cookie,
http-only在后端配了,前端也未必收得到










