近期业务线上出现问题,嵌套的页面莫名丢失cookie;
经深入排查,发现新版本的chrome浏览器(80版本之后)对cookie的校验更加严格,有页面嵌套的可能会出现问题。
chrome升级到80版本之后(最坑的地方:灰度测试,即也可能存在同一版本不同人的浏览器表现不同),cookie的SameSite属性默认值由None变为Lax,该问题的讨论可参考:https://github.com/google/google-api-javascript-client/issues/561
在Lax模式下,以下类型请求将受影响:
请求类型 | 示例 | 正常情况 | Lax |
---|---|---|---|
链接 | <a href="..."></a> | 发送 Cookie | 发送 Cookie |
预加载 | <link rel="prerender" href="..."/> | 发送 Cookie | 发送 Cookie |
GET 表单 | <form method="GET" action="..."> | 发送 Cookie | 发送 Cookie |
POST 表单 | <form method="POST" action="..."> | 发送 Cookie | 不发送 |
iframe | <iframe src="..."></iframe> | 发送 Cookie | 不发送 |
AJAX | $.get("...") | 发送 Cookie | 不发送 |
Image | <img src="..."> | 发送 Cookie | 不发送 |
解决方法1:
下面的设置无效。
Set-Cookie: widget_session=abc123; SameSite=None
下面的设置有效。
Set-Cookie: widget_session=abc123; SameSite=None; Secure
解决方法2:
两个跨域的网站部署到一起,例如
www.xxx.com/A网站
www.xxx.com/B网站
解决问题3:
谷歌浏览器里面:
chrome://flags/
把SameSite by default cookies这个参数设置成disabled
解决方法4
修改应用服务器方式
1.tomcat:
首先你需要在httpd.conf文件中开启mod_header模块
LoadModule headers_module modules/mod_headers.so
你打开它以后并不能生效,所以我们还要重写Set-Cookie的头信息,其他的方法我们已经尝试并不可行,目前只有这一种方法可行
Header always edit "Set-Cookie" "path=/" "path=/; Secure; SameSite=None"
对应windows下的apache
Header edit "Set-Cookie" "path=/" "path=/; Secure; SameSite=None"
对应linux下的apache
这里修改完有些人可能不生效,关键字就是always 如果你加了always不生效就去掉,反之则加上
2.nginx
在 nginx 的 location 中配置
proxy_cookie_path / "/; httponly; secure; SameSite=None";
示例
server {
listen 443 ssl http2;
server_name www.cat73.org;
ssl_certificate /etc/letsencrypt/live/cat73.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cat73.org/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/cat73.org/chain.pem;
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options SAMEORIGIN;
add_header Strict-Transport-Security "max-age=15768000";
location / {
root /var/www/html;
}
location /api {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 在这里设置
proxy_cookie_path / "/; httponly; secure; SameSite=Lax";
}
}