大家好,又见面了,我是你们的朋友全栈君。
最近在使用前后端分离开发的时候,遇到了一个诡异的问题,无论如何设置跨域,同一个页面获取到的session始终不一致。
发现问题:
登录界面前后端分离,ajax提交登录时出错 验证码接口和登录接口的session不一致(跨域问题) 在网上搜索跨域问题,重新设置,问题依旧
错因排除:
ajax允许cookie(已经设置 xhrFields: { withCredentials: true} ) springboot尝试设置了多种跨域方法(springboot解决跨域)
深入分析:
使用其它浏览器(firefox, ie),session却是一致的
对比chrome和firefox请求头和响应头:
firefox:首次发起请求后,服务端返回sessionId后,之后每次请求中的cookie都会带上sessionId。 chrome:请求头始终未携带sessionId,甚至整个cookie都为空,导致服务器每次都接受不到sessionId,每次都会重新分配 一 个 session。
探寻解决方案:
在配置类中设置SameSite=null
:
@Configuration
public class SpringSessionConfig {
@Bean
public CookieSerializer httpSessionIdResolver() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
...
cookieSerializer.setSameSite(null);
...
}
}
注意,你的项目如果未做session分布式管理,可能需要引入以下依赖才能使用上述类。至于不同Chrome版本号的问题可以参考这篇文章:关于解决Chrome新版本中cookie跨域携带和samesite的问题处理
代码语言:javascript复制<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-core -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
最终解决方案: 继续查找资料的时候,幸运的找到了github上对于该问题的探究:New cross-site cookie not ‘SameSite’ warning in Chrome
看到其中的一条解决方案: 禁用chrome samesite。方法如下: 1.在chrome中打开链接: chrome://flags/#site-isolation-trial-opt-out,搜索samesite
2.将上述三个选项禁用(设为disable)后重启chrome,问题解决
总结:
存在即合理,SameSite
的设计初衷是为了防止CSRF攻击,禁用SameSite实际上并没有解决问题,属于下下策。这里提供一下我的理解,SameSite为了防止CSRF
攻击,加强了对cookie的管理,防止用户带着cookie去访问第三方网站,而这又涉及到了跨域问题。然而,我们不可能要求用户像我们一样去禁用新版chrome的SameSite,目前的建议就是在header中设置samesite,即上述的response.setHeader("Set-Cookie", "HttpOnly;Secure;SameSite=None")
后,使用https传输cookie。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/133162.html原文链接:https://javaforall.cn