博客列表 >cookie之SameSite属性

cookie之SameSite属性

弘德誉曦的博客
弘德誉曦的博客原创
2020年09月28日 09:42:427761浏览

cookie之SameSite属性

新版chrome跨域问题:cookie之SameSite属性
原创dominx 最后发布于2020-03-16 16:00:02 阅读数 299 收藏
展开
最近在使用前后端分离开发的时候,遇到了一个诡异的问题,无论如何设置跨域,同一个页面获取到的session始终不一致。

事情的起始大概是这样的:

首先说一下我的业务逻辑,其实就是最常见的登录功能,获取验证码后存入session,用户提交登录时,将用户提交的验证码与从session里获取的验证码进行对比;功能简单,也好理解。可是却遇到了如下一系列问题:

发现问题:

登录界面前后端分离,ajax提交登录时出错。
验证码接口和登录接口的session不一致(跨域问题);
在网上搜索跨域问题,重新设置,问题依旧。
错因排除:

ajax允许cookie(已经设置 xhrFields: { withCredentials: true} )。
springboot尝试设置了多种跨域方法(springboot解决跨域)。
深入分析:

使用其它浏览器(firefox, ie),session却是一致的。。
对比chrome和firefox请求头和响应头:
firefox:首次发起请求后,服务端返回sessionId后,之后每次请求中的cookie都会带上sessionId。

chrome:请求头始终未携带sessionId,甚至整个cookie都为空,导致服务器每次都接受不到sessionId,每次都会重新分 配 一 个 session。

出现转机:
搜索chrome未携带cookie原因,发现cookie新属性:SameSite(chrome77版本后支持) 。对该属性的介绍可以参考这篇文章:SameSite。同时,查看chrome的cookie,由于没有指明SameSite的取值,chrome默认将其设置为了Lax:
在这里插入图片描述

寻找解决方案:

DefaultCookieSerializer(待解决)
翻到不少博客说可以使用DefaultCookieSerializer通过如下代码设置SameSite,然后我的项目中并没有CookieSerializer以及DefaultCookieSerializer这两个类,,原因暂且未知。

@Bean
public CookieSerializer httpSessionIdResolver() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setSameSite(null);
return cookieSerializer;
}
设置CookieProcessor(待解决)
全局搜索SameSite,发现tomcat下的CookieProcessor提供了setSameSiteCookies方法,可是设置后无效,,可能是使用方法不对。

设置response的header(推荐)
通过在后端中设置response.setHeader(“Set-Cookie”, “HttpOnly;Secure;SameSite=None”),响应头可以看到设置的Set-Cookie,但是chrome提示 如下:
在这里插入图片描述

由于设置SameSite为NONE时,需要同时设置secure,不设置secure无效,而设置secure之后,必须使用https来传输cookie。相对来说较为安全。

我的最终方案:
继续查找资料的时候,幸运的找到了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。

时间问题文章逻辑可能并不严谨,仅供参考,如发现错误欢迎指正。
————————————————
版权声明:本文为CSDN博主「dominx」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38527695/article/details/104899751

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议