欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot2.x版本中,使用SpringSession踩的坑及解决

程序员文章站 2022-03-05 20:30:55
springboot2.x springsession踩坑exception encountered during context initialization - cancelling refres...

springboot2.x springsession踩坑

exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.beancreationexception: error creating bean with name ‘org.springframework.boot.autoconfigure.session.sessionautoconfiguration$servletsessionrepositoryvalidator': invocation of init method failed; nested exception is org.springframework.boot.autoconfigure.session.sessionrepositoryunavailableexception: no session repository could be auto-configured, check your configuration (session store type is ‘redis')

这是因为缺少了spring-session-data-redis依赖。

关于springboot2.x中,引用springsession,同时使用redis存储缓存数据需要进行如下配置:

 <!--springsession依赖-->
 <dependency>
  <groupid>org.springframework.session</groupid>
  <artifactid>spring-session-core</artifactid>
 </dependency>
 <!--springsessionredis依赖-->
 <dependency>
  <groupid>org.springframework.session</groupid>
  <artifactid>spring-session-data-redis</artifactid>
 </dependency>
#使用使用redis缓存session数据
spring.session.store-type=redis
#redis服务器地址
spring.redis.host=127.0.0.1
#redis服务器端口号
spring.redis.port=6379

总结:

在springboot2.x的版本中,引用spring-session-core时,不是对spring-session-data-redis进行加载,需要用户自己添加关于spring-session与redis的关联依赖。

springboot 2.x 踩坑——跨域导致session问题

目前it界主流前后端分离,但是在分离过程中一定会存在跨域的问题。

什么是跨域?

是指浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。

遇到的场景

当我们用springboot + shrio +vue 来做后台管理的项目时,无法获取shirosession当前登录的用户,

于是我们就排查,网上说在跨域时让session通过就可以了

后端

@configuration
public class corsconfig {
    private corsconfiguration buildconfig() {
        corsconfiguration corsconfiguration = new corsconfiguration();
        corsconfiguration.setallowcredentials(true);
        // 允许任何域名使用
        corsconfiguration.addallowedorigin("*");
        // 允许任何头
        corsconfiguration.addallowedheader("*");
        // 允许任何方法(post、get等)
        corsconfiguration.addallowedmethod("*");
        corsconfiguration.setmaxage(3600l);
        return corsconfiguration;
    }
    @bean
    public corsfilter corsfilter() {
        urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource();
        // 对接口配置跨域设置
        source.registercorsconfiguration("/**", buildconfig());
        return new corsfilter(source);
    }
}

前端

axios.defaults.withcredentials=true; 

但是设置后依旧不行

经过一天的百度与排查,我回滚到springboot 1.x 居然没有这个问题,才定位到是升级到springboot 2.x导致的原因,好了,已经抓住凶手了,这下子好对症下药了,去网上看了 springboot升级到2.x spring 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设置为空

@configuration
public class springsessionconfig { 
    @bean
    public cookieserializer httpsessionidresolver() {
        defaultcookieserializer cookieserializer = new defaultcookieserializer();
        // 取消仅限同一站点设置
        cookieserializer.setsamesite(null);
        return cookieserializer;
    }
}

问题解决!!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。