Nginx设置cookie的SameSite,解决:A cookie associated with a cross-site resource at was set without the SameSite

时间:2022-06-01 16:55:03

谷歌浏览器80版本后,默认值改为Lax,导致跨域访问中报错,类似:

A cookie associated with a cross-site resource at was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

SameSite属性

这是从Chrome 51 开始,Cookie 新增加了一个SameSite属性,它是用来限制第三方 Cookie,防止 CSRF 攻击和用户追踪。

SameSite属性有三个值:Strict,Lax和None。

Strict

Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

Lax

Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

Set-Cookie: CookieName=CookieValue; SameSite=Lax;

导航到第三方网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。而对于Post 表单,Ajax,iframe和image请求,均不会发送cookie信息。在Chrome 51后的浏览器,设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。

None

我们可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

下面的设置无效。

Set-Cookie: widget_session=abc123; SameSite=None

下面的设置有效。

Set-Cookie: widget_session=abc123; SameSite=None; Secure

Nginx设置SameSite

Nginx可以在location里设置

server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/letsencrypt//fullchain.pem;
ssl_certificate_key /etc/letsencrypt//privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/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";
}
}