1.验证码及登录、session
(1) 问题
谷歌的samesite同站问题,并非是跨域的问题,在前后端分离下,前端与后端联调,每次都会发送的新的请求(get请求可以传),不能把上次的请求session带回来,其流程是:
获取验证码:浏览器发起请求,由于是在前端的项目发起,前端ip与请求接口的不是同源同站,相当于新的请求,不传session给后台,后台于是接收请求,也是判断为新的请求,把session返回给浏览器,浏览器set-cookie,这是第一次请求,后续每次请求都是新的set-cookie。
登录:前端在login时,也是发起新的请求,由于与验证码的session不一致,无法校验,如果一致就没问题,但是问题就在这里,由于浏览器不传回session,无法进行校验。
(2) 解决方案
1.后端对session用redis进行保存,访问验证码的时候返回一个随机字符串和验证码,同时也存到redis,随机字符串:验证码,再给个有效期,模拟session,login时把随机字符串放请求头,然后在redis里读取随机字符串,校验验证码,无论校验成功与否,去掉redis里的随机字符数据。
2.开发时,前端做个内置的反向代理,原理:浏览器访问反向代理,认为是同一台电脑,无同站问题,会发送session给代理,后端就接收到。
3.生产环境即部署时,我做的是放在同一台电脑上,可以用nginx做反向代理,不会产生问题,因为浏览器认为调用的地址与后端是同一个ip地址,简易的教程https://blog.csdn.net/qq_38247316/article/details/120908595,
4.部署到后端上,也可以规避这个问题,本质上还是发布到了后端的服务器上,所以不会出现这个问题。
5.升级成https,后端设置相应的请求头,可以用过滤器添加,我个人条件有限,未能实现效果。
6.获取验证码的时候,后端设置一个与前端约定好的请求头,后端可以用uuid填充,再放入一个map里,然后用该请求头代替session。
(3) 具体解释
Cookie 的 SameSite 属性 - 阮一峰的网络日志 (ruanyifeng.com)
(4) 我的环境
后端:spring boot+已配置跨域
前端: react
2.nginx如何规避samasite
(1) 配置
server {
listen 8850;
server_name 192.168.aa.bb;
charset utf-8;
#charset koi8-r;
#access_log logs/host.access.log main;
location = /login.html {
root html;
}
location ~* .(jpg|gif|png|js|css)$ {
root html;
if (-f $request_filename) {
expires max;
break;
}
}
location / {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
proxy_send_timeout 12s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
#proxy_set_header Host $host;
}
(2) 注意点
server_name proxy_pass 可以不相同,且是前后端部署在同一个电脑上,前端打包好的放在nginx上,通过转发请求到后端。
如前端部署的地址:http://192.168.a.b:8850/login.html
前端访问后端的访问地址必须是:http://192.168.a.b:8850 开头的
(3) 原理
nginx部署项目后,浏览器认为前端部署的地址和请求的地址及端口是严格同站的,认为是同一个组织的,请求的时候,会带上cookie,不然会每次请求返回的都是新的session,此处是为了解决登录的问题。
nginx本身把收到的请求转发出去,去请求数据,然后返回。
(4) 实测
sid为后台我设置的sessionid,实际上去请求会携带这个session。
第一次是set-cookie,第二次以后才携带,且get是不受samesite影响的。
host:是指这请求要去的地址,下述去的9000,未携带cookie
origin:用来说明请求从哪里发起的,包括,且仅仅包括协议和域名。
referer:告知服务器请求的原始资源的URI,其用于所有类型的请求,并且包括:协议+域名+查询参数(注意,不包含锚点信息)。
因为原始的URI中的查询参数可能包含ID或密码等敏感信息,如果写入referer,则可能导致信息泄露,所以尽量不要用这种方式提交。
未携带cookie。
携带cookie