编辑
2024-04-06
后端
00
请注意,本文编写于 308 天前,最后修改于 305 天前,其中某些信息可能已经过时。

目录

1 前端设置
2 后端设置
3 代理设置

image-20240408100632322

后端使用cookie记录登录信息时,登录完成后响应头会携带Set-Cookie属性,浏览器会识别Set-Cookie并在满足一些条件后将Cookie注入浏览器中。

这里的请求它如果是跨域(前端域名和后端域名不一致)的,那么Cookie将无法注入。

1 前端设置

跨域请求的情况下,浏览器默认禁止携带cookie,如果想携带cookie,需要在请求时设置withCredentials参数为true,fetch请求的设置方法为method.config.credentials = 'include'

当请求的credentials模式为include时,响应头Access-Control-Origin的值不可以是*,也就是说服务端的cors插件的origin参数,必须指定具体域名,而不能是*这种通配符

在这个设置后的Cookie注入情况

8559f98dc9ab4d7dc5e3a969cb213de0

2 后端设置

前端设置完毕后,将开始设置后端,后端主要设置SameSite

SameSite允许我们声明 cookie 可以用来 first-party 或者 same-site。它会明确的给出“网站”是指哪些(哪些可以带 cookie)。网站由域名后缀和域名前部分组成,比如www.web.devweb.dev的一部分。

SameSite属性提供了三种不同的方式来管理 cookie,你可以不指定这个属性(None),或者使用StrictLax来限制 cookie 的 same-site 请求。

Strict

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

这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。

Lax

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

导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。

请求类型示例正常情况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不发送

设置了StrictLax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

None

这种情况下允许在 third-party 发送请求时使用 cookie

但是设置SameSiteNone时需要同时设置Secure,Cookie 只能通过 HTTPS 协议发送),否则无效。

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

在我们的后端并没有设置HTTPS协议,故通过设置SameSite的方式完全无效了,我们选择通过代理的方式设置。

这块设置完后的Cookie注入情况

ea565c6f5879015f8b07c432d14101e3

3 代理设置

在生产环境中,我们可以通过设置前端的Nginx代理服务器,设置后端服务反向代理到前端的域名上(或者前端反向代理到后端服务器上也是一样的)这样就从根源上解决了跨域问题。

Nginx配置如下

nginx
# 代替vite 中的代理服务 功能 反向代理后端域名到 前端 location /api { proxy_pass http://xx.xx.xx.xx:xx; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }

这个时候,请求前端域名http://localhost:5173/api就相当于请求后端域名的http://xx.xx.xx.xx:xx/api,注意Nginx是没有重写功能的,故必须配置后端的请求路径

yaml
servlet: context-path: /api

这个时候就可以正常的注入Cookie了

开发环境中的前端配置,需要通过 Vite 的代理服务器实现,具体配置如下,基本都会的

js
server: { // 指定dev sever的端口号,默认为5173 port: env.VITE_APP_PORT, // 自动打开浏览器运行以下页面 // open: '/', // 设置反向代理 proxy: { // 以下示例表示:请求URL中含有"/api",则反向代理到http://localhost // 例如: http://localhost:3000/api/login -> http://localhost/api/login // 如果反向代理到localhost报错Error: connect ECONNREFUSED ::1:80, // 则将localhost改127.0.0.1 '/api': { target: env.VITE_API_URL, changeOrigin: true, // rewrite: (path) => path.replace(/^\/api/, ''), }, }, },
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:peepdd864

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!