Spring ResponseCookie设置Cookie Max-Age为PT168H格式是否为Bug?
结论
这个现象不是Spring框架当前维护版本的Bug,由两个问题共同导致:一是对maxAge方法的参数单位理解错误,二是使用了存在早期序列化缺陷的Spring旧版本,加上手动序列化Cookie的写法不规范。
具体原因
maxAge参数单位理解错误:ResponseCookie中接收long类型的maxAge(long maxAge)重载方法,参数单位是秒,不是毫秒。你写的1000 * 60 * 60 * 24 * 7是按毫秒计算的7天数值,直接传入会让实际有效期放大1000倍,7天对应的正确秒数是7 * 24 * 60 * 60 = 604800。- 旧版本序列化缺陷:你看到的
Max-Age=PT168H是JavaDuration类的标准ISO-8601时间周期格式,完全不符合Set-Cookie头要求的纯数字秒数规范。这个问题仅存在于Spring Framework 5.0.0~5.0.2的早期版本中,当时ResponseCookie.toString()方法没有将Duration类型的maxAge转换为秒数字符串,直接输出了Duration对象本身的字符串格式,这个缺陷在5.0.3版本就已经修复。 - 写法不规范:你不需要手动调用
headers.set(HttpHeaders.SET_COOKIE, cookie.toString())设置Cookie,这种手动序列化的方式很容易受版本缺陷影响,Spring本身提供了专门的Cookie设置API,会自动按照RFC规范序列化Cookie内容。
正确实现代码
@GetMapping("getCookieUsingResponseCookie") public ResponseEntity<?> getCookieUsingResponseCookie() { Duration expireDuration = Duration.ofDays(7); ResponseCookie cookie = ResponseCookie.from("LWSSO_COOKIE_KEY","123-LWSSO_COOKIE_KEY-VALUE-456") .domain("localhost") .httpOnly(true) .maxAge(expireDuration) .path("/") .secure(true) .build(); // 直接使用ResponseEntity内置的cookie方法设置,无需手动操作请求头 return ResponseEntity.ok() .cookie(cookie) .build(); }
如果要使用long类型参数设置有效期,直接传入秒数即可,不要额外乘1000转毫秒:
.maxAge(7 * 24 * 60 * 60) // 对应7天有效期
内容的提问来源于stack exchange,提问作者Oxnard
相关产品推荐
相关产品推荐

