聊聊Springboot2.x的session和cookie有效期
作者:Agly_Charlie 发布时间:2022-09-11 10:17:20
Springboot2.x的session和cookie有效期
session和cookie的相关区别和联系就不介绍了,这里就记录一下笔记。
背景
最近在做单点登录CAS的问题,在后端塞一个cookie uid用于前端的登录拉起,并且设置了max-age, 但是测试的时候,一直有个问题,就是前端页面打开,不做任何操作,停留30分钟左右,然后点击按钮,按理说是应该会发送到后端,但是实际上却发生了302的跳转,前端也没有拉起登录页面,说明登录状态还在(根据uid判断),但是为什么后端日志没有打印??
也就是说,页面半小时左右没做任何操作,这个按钮就跳出了前端和后端,失去了控制,百思不得其解啊。
经过一番排查,终于发现问题了,前端的登录态判断条件,uid是后端塞进去的,并且设置了max-age为1小时,但是项目里的springboot2.x,并没有配置下面内容:
server.servlet.session.timeout= # session的有效期,默认为30min
server.servlet.session.cookie.max-age= #cookie的有效期,默认为-1 即是和浏览器关闭状态有关
后来测试了一番,在代码里add cookie和 server.servlet.session.cookie.max-age 之间的参数比较
public int test(HttpServletRequest request, HttpServletResponse response) {
int maxInactiveInterval = request.getSession().getMaxInactiveInterval();
Cookie[] cookies = request.getCookies();
System.out.println("maxInactiveInterval: " + maxInactiveInterval);
Cookie cookie = new Cookie("uid","koo");
cookie.setMaxAge(5);
response.addCookie(cookie);
return maxInactiveInterval;
}
测试策略为:
设置server.servlet.session.cookie.max-age 和 cookie.setMaxAge(5);的值不一样,然后在浏览器查看。
最后的结论是:
server.servlet.session.cookie.max-age控制的是JESSIONID的有效期,Cookie cookie = new Cookie(“uid”,“koo”); cookie.setMaxAge(5);这种方式的cookie 特定字段的有效期是分开的。
另外一个配置:
server.servlet.session.timeout表示的是session的有效期,查看源代码默认值为:30min,或者也可以这样输出session的有效期:int maxInactiveInterval = request.getSession().getMaxInactiveInterval();
项目问题解释
我在项目里只有Cookie cookie = new Cookie(“uid”,“koo”); cookie.setMaxAge(3600); 并且是设置为3600秒的有效期,但是服务器的session有效期server.servlet.session.timeout是没有配置的,所以前端登录态判断的时候,uid是还存在的,所以发送请求的时候,不会拉起登录页面,会把请求发送出去,但是后端的session已经过期了,导致发生302的请求,请求看起来失去了控制。
最后解决办法为
server.servlet.session.timeout=86400
server.servlet.session.cookie.max-age=86400
Cookie cookie = new Cookie(“uid”,“koo”);
cookie.setMaxAge(23*3600);
response.addCookie(cookie);
登录态字段的cookie有效期要小于session的有效期,这样就会在先于发送请求的时候,拉起登录页面了,不会再出现失去控制的情况。
升级springboot 2.x 踩过的坑——跨域导致session问题
目前IT界主流前后端分离,但是在分离过程中一定会存在跨域的问题。
什么是跨域?
是指浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。
做过web后台的童鞋都知道,跨域这种问题是比较常见的,最近我们公司需要将springboot 1.x升级到2.x,在升级之后遇到了挺多的问题,例如某些类过时了或者某些类找不到等,还有就是今天要说得session不一致的情况(eg:请求不同接口,sessionID都不一致,即session不会共享)。
场景
今天前端童鞋跟我说,本地环境调用校验验证码接口一直报“未获取到用户信息,请重新登录”,我直接看了下这个接口,他是从session中获取的用户信息,如果用户不存在则会抛这种提示语。
HttpSession session = request.getSession(false);
Object sessionObj = session.getAttribute(LOGIN_NAME);//session为空
String currentName = null == sessionObj ? null : sessionObj.toString();
if (StringUtils.isBlank(currentName)) {
res.setMessage(messageUtil.getMessage("reLogin"));
res.setStatusCode(StatusCode.RE_LOGIN.getCode());
return res;
}
因为我们登录和校验验证码是两个接口,所以用户信息是从登录放进去的,然后在验证码接口中获取用户信息做后面的进一步操作。
看到这个之后,我看了下springboot的配置,都有配置session 共享的配置,而且我的session是放在redis里面的,有点郁闷,然后我就登录到测试环境登录一下试试看,咦~~居然可以,最后才反应过来是跨域的问题,然后我又去看了下代码,是有配置跨域的问题,真奇怪!
经过一天的百度与排查,我回滚到springboot 1.x居然没有这个问题,才定位到是升级到springboot 2.x导致的原因,好了,已经抓住凶手了,这下子好对症下药了,去网上看了 springboot升级到2.xspring session 相关的问题。
终于发现了新大陆,spring-session 2.x 中 Cookie里面居然引入了SameSite 这个叼毛,他默认值是 Lax,好了咱们来看看这个是什么东西?
SameSite Cookie 是用来防止CSRF攻击,它有两个值:Strict、Lax
SameSite = Strict:
意为严格模式,表明这个cookie在任何情况下都不可能作为第三方cookie;
SameSite = Lax:
意为宽松模式,在get请求是可以作为第三方cookie,但是不能携带cookie进行跨域post访问(这就很蛋疼了,我们那个校验接口就是POST请求)
总结
前端请求到后台,每次session都不一样,每次都是新的会话,导致获取不到用户信息
解决方案
将SameSite设置为空
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@Configuration
public class SpringSessionConfig {
public SpringSessionConfig() {
}
@Bean
public CookieSerializer httpSessionIdResolver() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// 取消仅限同一站点设置
cookieSerializer.setSameSite(null);
return cookieSerializer;
}
}
pom.xml依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
来源:https://blog.csdn.net/Agly_Clarlie/article/details/90050740


猜你喜欢
- 本文实例为大家分享了Java实现简单万年历的具体代码,供大家参考,具体内容如下1 要求1、输入年份;2、输入月份;3、输出某年某月的日历。2
- 本文主要介绍了java中LinkedList使用迭代器优化移除批量元素原理,分享给大家,具体如下:public interface Iter
- for循环for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构。for循环执行的次数是在执行前就确定的。语法格式如下:for(
- 文件上传和下载是web开发中常遇到的问题,这几天在做一个项目又用到了文件下载,之前也零零散散记了些笔记,今天来做一下整理。文件上传还有待进一
- 零、动态库 System.Math.dll引入动态库 using System.Math;Math 为通用数学函数、对数函数、三角函数等提供
- 写在前面在前后端交互过程中,为了保证信息安全,我们往往需要加点用户验证。本文介绍了用springboot简单整合token。springbo
- JDK、JRE、JVMJDK包含JRE,而JRE包含JVMJDK(Java Development Kit)是针对Java开发员的产品,是整
- 一、题目描述-批量重命名1、题目题目:在window操作系统中,支持对文件名重命名,但不支持批量重命名。实现:做一个批量重命名的工具。2、解
- 一.抽象类(一)概念 在继承的层次结构中,每个新的子类都使类变得更加明确和具体。如果从一个子类向父类
- package test001;import java.awt.event.ActionEvent;import java.awt.even
- 一、关键字分类C语言一共多少个关键字呢?一般的书上,都是32个(包括本书),但是这个都是C90(C89)的标准。其实C99后又新增了5个关键
- 代理模式:为其他对象提供一种代理以控制某个对象的访问。用在:在某些情况下,一个客户不想或者不能直接访问另一个对象,而代理对象可以在客户端和目
- package com.qhdstar.java.pdf;import java.awt.Color;import java.io.File
- 一 前言在elasticsearch\config目录下,有三个核心的配置文件:elasticsearch.yml,es相关的配置。jvm.
- (1) main.xml 代码如下:(声明四个按钮控件) XML代码: <?xml version="1.0" e
- 一、回顾Stream管道流操作通过前面章节的学习,我们应该明白了Stream管道流的基本操作。我们来回顾一下:源操作:可以将数组、集合类、行
- 在winform里拖入一个datagridview控件,跟一个openfiledialog控件using System;using Syst
- Maven,是一个Java开发比较常用的项目管理工具,可以对 Java 项目进行构建、依赖管理。对于很多Java程序员来说,分层架构都是不陌
- Solr我还是个菜鸟,写这一些文章只是记录一下最近一段时间学习Solr的心得。 Solr是什么? 最近我学Solr的时候,一直看到一句话,S
- Scala小程序详解1. 交互式模式在命令行窗口中,输入Scala命令:xiaosi@Qunar:~$ scalaWelcome to S