导读:本期聚焦于张立峰创作的《Spring Boot 中如何设置、读取 Cookie 并配置 SameSite 属性?》,敬请观看详情。浏览器默认开启 SameSite 属性后,不少老项目的登录态突然失效,排查半天才发现问题出在 Cookie 上。本文围绕 Spring Boot 场景,系统讲解 Cookie 的完整操作方法:如何通过 Servlet 原生 API 和 ResponseCookie 新式写法写入 Cookie,如何在 Controller 中读取指定 Cookie 值,以及 Cookie 的生命周期、路径、HttpOnly、Secure 等常用属性该怎么设置。重点分析 SameSite 三种取值 Lax、Strict、None 的区别,给出通过 Tomcat 的 CookieProcessor 和 Spring Boot 配置项全局修改 SameSite 的两种方案,并说明 SameSite=None 必须搭配 Secure 的强制要求,帮助你彻底解决跨站请求 Cookie 携带问题。

Cookie 是 Web 开发里最古老也最常用的状态保持手段,登录会话、埋点标识、主题偏好都离不开它。不过在 Spring Boot 项目里,Cookie 的操作方式和普通 Java Web 有一些细节差异,尤其是 Chrome 从 80 版本开始默认把未声明 SameSite 的 Cookie 按 Lax 处理之后,跨站场景下 Cookie 不携带的问题频频出现。这篇文章把 Cookie 的写入、读取、属性配置和 SameSite 的全局设置一次性讲清楚。

Spring Boot 中如何设置、读取 Cookie 并配置 SameSite 属性?

一、在 Spring Boot 中设置 Cookie 的两种方式

第一种是直接使用 Servlet 原生 API。Spring MVC 的 Controller 方法参数中可以直接注入 HttpServletResponse,然后通过 javax.servlet.http.Cookie(新版本是 jakarta.servlet.http.Cookie)构造对象,再调用 addCookie 写入响应。这种方式最直观,兼容性也最好。

@GetMapping("/login")
public String login(HttpServletResponse response) {
    Cookie cookie = new Cookie("token", "abc123");
    cookie.setHttpOnly(true);        // 禁止 JS 读取,防 XSS 窃取
    cookie.setSecure(true);          // 仅 HTTPS 下发送
    cookie.setPath("/");             // 生效路径
    cookie.setMaxAge(7 * 24 * 60 * 60); // 存活 7 天,单位秒
    response.addCookie(cookie);
    return "ok";
}

需要注意的是,setMaxAge 的取值有三种含义:正数表示存活指定秒数;负数表示会话级 Cookie,浏览器关闭即失效(默认值就是 -1);0 表示立即删除该 Cookie,这是删除 Cookie 的标准做法。

第二种方式是使用 Spring 5 引入的 ResponseCookie。它采用链式构造器的写法,支持直接设置 sameSite 属性,这是原生 Cookie 类做不到的。如果你的项目前后端分离、需要精细控制 Cookie 属性,推荐用这种写法。

@GetMapping("/login2")
public String login2(HttpServletResponse response) {
    ResponseCookie cookie = ResponseCookie.from("token", "abc123")
            .httpOnly(true)
            .secure(true)
            .path("/")
            .sameSite("Lax")   // 可直接指定 Lax / Strict / None
            .maxAge(Duration.ofDays(7))
            .build();
    response.addHeader("Set-Cookie", cookie.toString());
    return "ok";
}

两种方式的本质都是往响应头里写 Set-Cookie 字段,区别只在于 API 的封装层次。ResponseCookie 会自动处理属性拼接和编码问题,出错概率更低。

二、在 Controller 中读取 Cookie

读取 Cookie 最常用的方式是借助 @CookieValue 注解,直接把某个 Cookie 的值绑定到方法参数上,代码非常简洁。

@GetMapping("/user")
public String getUser(@CookieValue("token") String token) {
    // 直接拿到名为 token 的 Cookie 值
    return "当前 token:" + token;
}

如果 Cookie 可能不存在,@CookieValue 会直接抛出异常,所以更稳妥的写法是加上 required = false 并给默认值:

@GetMapping("/user")
public String getUser(@CookieValue(value = "token", required = false, defaultValue = "") String token) {
    if (token.isEmpty()) {
        return "未登录";
    }
    return "当前 token:" + token;
}

当需要遍历所有 Cookie 时,可以注入 HttpServletRequest,调用 getCookies() 拿到数组后逐个筛选。这种方式适合写拦截器或过滤器,比如统一提取登录态。

@GetMapping("/cookies")
public String list(HttpServletRequest request) {
    Cookie[] cookies = request.getCookies();
    if (cookies == null) {
        return "没有任何 Cookie";
    }
    for (Cookie c : cookies) {
        System.out.println(c.getName() + " = " + c.getValue());
    }
    return "已打印到控制台";
}

有一点要提醒:Cookie 是随请求自动携带的,浏览器只会把满足 Domain 和 Path 匹配条件的 Cookie 发给服务端。如果发现 Cookie 读不到,先用浏览器开发者工具的 Network 面板确认请求头里有没有 Cookie 字段,再检查设置时的 Path 是否写成了过窄的路径。

三、SameSite 属性详解与全局配置

SameSite 是用来防御 CSRF 攻击的 Cookie 属性,它控制浏览器在跨站请求时是否携带 Cookie,共有三个取值。Strict 最严格,任何跨站请求都不带 Cookie,即使用户从别的网站点链接跳转过来也不会带,安全性最高但体验有损。Lax 是目前的浏览器默认值,顶级导航的 GET 请求(比如点击链接)会带 Cookie,但表单提交、iframe、Ajax 跨站请求都不带,安全和体验比较均衡。None 则完全不做限制,跨站请求照样携带,但必须同时设置 Secure=true,也就是只能在 HTTPS 环境下生效,否则浏览器会直接拒绝这个 Cookie。

典型的踩坑场景:前后端分离部署在不同域名下,前端用 withCredentials: true 发跨域请求,但后端设置的 Cookie 没有声明 SameSite,浏览器按 Lax 处理,跨站请求根本不带 Cookie,登录态自然丢失。解决思路有两个层面。

第一种是针对单个 Cookie,用前面提到的 ResponseCookie 直接指定 sameSite("None") 并开启 secure,精确控制。

第二种是全局配置。Spring Boot 内嵌 Tomcat 从 2.6 版本开始支持通过配置文件直接声明默认的 SameSite 策略,在 application.properties 中添加:

server.servlet.session.cookie.same-site=Lax
server.servlet.session.cookie.secure=true
server.servlet.session.cookie.http-only=true

这个配置只对 Spring Session 生成的会话 Cookie 生效。如果想影响所有经过 Tomcat 写出的 Cookie,可以自定义 CookieProcessor

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieCustomizer() {
    return factory -> {
        TomcatContextCustomizer customizer = context -> {
            LegacyCookieProcessor processor = new LegacyCookieProcessor();
            processor.setSameSiteCookies("Lax");
            context.setCookieProcessor(processor);
        };
        factory.addContextCustomizers(customizer);
    };
}

如果是 Filter 层面写入的认证 Cookie,还可以让过滤器继承 OncePerRequestFilter 并配合 CookieSerializer(Spring Session 提供)来统一控制序列化行为,这在多实例部署需要共享会话的架构里更常见。

最后强调一个硬性规则:SameSite=None 必须搭配 Secure 属性,且页面必须通过 HTTPS 访问。本地开发时如果用 http://localhost 调试,Chrome 对 localhost 有豁免,但 Firefox 不一定买账,最稳妥的办法还是给本地也配上自签证书,或者临时降级为 Lax 观察。掌握这些配置点后,无论是登录态维护还是跨域资源共享场景,Cookie 相关的问题都能快速定位和解决。

Spring BootCookieSameSite修改时间:2026-09-15 03:44:30

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260915/57013.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。