千家信息网

spring-session中怎么动态修改cookie的max-age

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家介绍spring-session中怎么动态修改cookie的max-age,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。使用spring-session时,动态修改
千家信息网最后更新 2026年11月02日spring-session中怎么动态修改cookie的max-age

这篇文章给大家介绍spring-session中怎么动态修改cookie的max-age,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

使用spring-session时,动态修改cookie的max-age

不论是使用spring提供的spring-session,还是使用servle容器实现的http session。原理都是把session-id以cookie的形式存储在客户端。每次请求都带上cookie。服务器通过session-id,找到session。

spring-session的使用

https://springboot.io/t/topic/864

由"记住我"引发的一个问题

用户登录的时候,通常需要一个【记住我】的选择框,表示是否要长期的保持会话。

【记住我】× 一般会把cookie的max-age设置为 -1,表示在浏览器关闭的时候,就自动的删除cookie。对于客户端而言关闭了浏览器,就是丢失了会话,需要重新的登录系统。特别在公共场合登陆了某些系统后,忘记执行'退出'操作,直接关闭了浏览器,后面使用电脑的人打开浏览器,也必须先登录才可以访问系统。这样在一定的程度上保证了安全性。

【记住我】√ 一般在自己私人电脑上选择,目的是为了避免重复的登录操作。登录成功,一般会把max-age的值设置为比较长,就算是关闭了浏览器。重新打开,也不需要再次执行登录操作。

spring-session 配置cookie的max-age属性

使用spring-session时,可以通过yml配置,或者代码配置的形式来设置max-age的属性。但是问题在于所有的session创建,都是使用同样的属性。在【记住我】这个功能上会出现一些问题

固定设置:max-age=-1,那么就算是勾选了【记住我】,也会因为浏览器关闭删除cookie,而丢失会话。下次打开浏览器还是需要重新执行登录

固定设置: max-age=604800(7天),那么用户在未勾选【记住我】的情况下,关闭浏览器。cookie并不会被立即删除,任何人再次打开这个系统。都不需要登录就可以直接操作系统。

总的来说就是,固定的max-age属性,会导致【记住我】功能失效。

使用spring-session时的解决方案

spring-session 通过接口 CookieSerializer,来完成对客户端cookie的读写操作。并且提供了一个默认的实现类: DefaultCookieSerializer。我们想要动态的修改cookie的max-age属性,核心方法在于。

@Overridepublic void writeCookieValue(CookieValue cookieValue) {        ...        StringBuilder sb = new StringBuilder();        sb.append(this.cookieName).append('=');        ...        int maxAge = getMaxAge(cookieValue);  // 读取maxAge属性        if (maxAge > -1) {                sb.append("; Max-Age=").append(cookieValue.getCookieMaxAge());                ZonedDateTime expires = (maxAge != 0) ? ZonedDateTime.now(this.clock).plusSeconds(maxAge)                                : Instant.EPOCH.atZone(ZoneOffset.UTC);                sb.append("; Expires=").append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));        }        ...}private int getMaxAge(CookieValue cookieValue) {        int maxAge = cookieValue.getCookieMaxAge();        if (maxAge < 0) {                if (this.rememberMeRequestAttribute != null                                && cookieValue.getRequest().getAttribute(this.rememberMeRequestAttribute) != null) {                        cookieValue.setCookieMaxAge(Integer.MAX_VALUE);                }                else if (this.cookieMaxAge != null) {                        cookieValue.setCookieMaxAge(this.cookieMaxAge);  // 如果 DefaultCookieSerializer 设置了maxAge属性,则该属性优先                }        }        return cookieValue.getCookieMaxAge(); // cookieValue 默认的maxAge属性 = -1}

可以看出,spring-session并没使用servlet提供的cookie api来响应cookie。而是自己构造Cookie头。而且还提供了Servlet还未实现的,Cookie的新属性:sameSite,可以用来防止csrf攻击。

覆写 DefaultCookieSerializer

import javax.servlet.http.HttpServletRequest;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.session.web.http.DefaultCookieSerializer;// @Componentpublic class DynamicCookieMaxAgeCookieSerializer extends DefaultCookieSerializer {                private static final Logger LOGGER = LoggerFactory.getLogger(DynamicCookieMaxAgeCookieSerializer.class);                public static final String COOKIE_MAX_AGE = "cookie.max-age";                @Value("${server.servlet.session.cookie.max-age}")        private Integer cookieMaxAge;                @Override        public void writeCookieValue(CookieValue cookieValue) {                HttpServletRequest request = cookieValue.getRequest();                // 从request域读取到cookie的maxAge属性                Object attribute = request.getAttribute(COOKIE_MAX_AGE);                if (attribute != null) {                        cookieValue.setCookieMaxAge((int) attribute);                } else {                        // 如果未设置,就使用默认cookie的生命周期                        cookieValue.setCookieMaxAge(this.cookieMaxAge);                }                if (LOGGER.isDebugEnabled()) {                        LOGGER.debug("动态设置cooke.max-age={}", cookieValue.getCookieMaxAge());                }                super.writeCookieValue(cookieValue);        }}

原理就是,把cookie的maxAge属性存储到request域。在响应客户端之前,动态的设置。

添加到IOC

import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.session.web.http.CookieSerializer;import com.video.manager.spring.session.DynamicCookieMaxAgeCookieSerializer;@Configurationpublic class SpringSessionConfiguration {                @Value("${server.servlet.session.cookie.name}")        private String cookieName;                @Value("${server.servlet.session.cookie.secure}")        private Boolean cookieSecure;        //      @Value("${server.servlet.session.cookie.max-age}")//      private Integer cookieMaxAge;                @Value("${server.servlet.session.cookie.http-only}")        private Boolean cookieHttpOnly;        @Value("${server.servlet.session.cookie.same-site}")        private String cookieSameSite;                @Bean        public CookieSerializer cookieSerializer() {                DynamicCookieMaxAgeCookieSerializer serializer = new DynamicCookieMaxAgeCookieSerializer();                serializer.setCookieName(this.cookieName);                // serializer.setCookieMaxAge(this.cookieMaxAge);                serializer.setSameSite(this.cookieSameSite);                serializer.setUseHttpOnlyCookie(this.cookieHttpOnly);                serializer.setUseSecureCookie(this.cookieSecure);                return serializer;        }}

使用 @Value,读取yml配置中的Cookie属性。

测试接口

import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import com.video.manager.spring.session.DynamicCookieMaxAgeCookieSerializer;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;@Controller@RequestMapping("/test")public class TestController {        static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);                @GetMapping("/session")        public ModelAndView session(HttpServletRequest request,                         @RequestParam("remember")Boolean remember) {                                HttpSession httpSession = request.getSession();                LOGGER.debug("httpSession={}", httpSession);                                if (!remember) {  // 不记住我                        // 设置cookie的生命周期为 -1                        request.setAttribute(DynamicCookieMaxAgeCookieSerializer.COOKIE_MAX_AGE, -1);                        // 设置session仅缓存30分钟                        httpSession.setMaxInactiveInterval(60 * 30);                }                                ModelAndView modelAndView = new ModelAndView("test/test");                return modelAndView;        }}

【记住我】√

http://localhost/test/session?remember=true

响应Cookie,存储时间是 7 天

redis的session存储,缓存时间是7天

【记住我】×

http://localhost/test/session?remember=false

响应Cookie,存储时间是:-1,临时会话设置成功,浏览器关闭Cookie删除

redis的session存储,缓存时间是30分钟,超过30分钟不活动,自动删除

关于spring-session中怎么动态修改cookie的max-age就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

属性 浏览器 浏览 登录 动态 存储 系统 客户 客户端 时间 配置 就是 缓存 问题 成功 内容 再次 功能 原理 周期 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 华服互联网科技怎么样 互联网和科技技术 科技互联网公司装修 中国 科技 互联网 青岛互联网科技公司 艾特科技互联网 深圳天众互联网科技公司 天扬科技互联网广告 互联网科技素材视频竖屏 联恩商钥互联网科技有限公司 汉立互联网科技有限公司联系电话 湖北码尼互联网科技有限公司电话 语蝶互联网科技有限公司 玉溪新华互联网科技好不好 长沙互联网科技 科技互联网的核心竞争力 2021互联网科技公司排名 郑州欣桑互联网科技有限公司 互联网科技职业技能培训学校 广西泛欧互联网科技有限公司 广州万易互联网科技有限公司 西安纸贵互联网科技有限公司 重生之互联网科技帝国 科技互联网项目 万易互联网科技有限公司 世界互联网领先科技成果 奇士达互联网科技 互联网巨头投资的硬核科技 恒生科技互联网指数分析 企晟互联网信息科技有限公司
0