目前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.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 { public SpringSessionConfig() { } @Bean public CookieSerializer httpSessionIdResolver() { DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); // 取消仅限同一站点设置 cookieSerializer.setSameSite(null); return cookieSerializer; } }
参考文章:
1、https://blog.csdn.net/qq_37060233/article/details/86595102
2、https://blog.csdn.net/boom_man/article/details/84642040
3、https://segmentfault.com/a/1190000017824101
4、https://segmentfault.com/a/1190000017175342?utm_source=tag-newest