目前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