chrome禁止三方cookie,网站登录不了怎么办

新版chrome(80+)浏览器默认屏蔽所有三方cookie已经不是什么新闻了,具体原因这里不去深究,有大量相关文章介绍,由于目前许多网站都依赖三方cookie,因此该特性的推出还是造成了一些的影响,比如收集用户信息的广告商,而且主流的浏览器都跟进chrome的策略,已经成为了既定事实,本篇文章主要聚焦于各种解决方案,大家可以针对自身情况采用不同的解决办法。

限制说明 SameSite

cookie新增的属性,取值包括:Lax(默认),None,Strict

1.None :将关闭SameSite属性,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效;

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

3.Lax :规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外,具体可参考文末链接【1】;

总数所述,要解决我们的问题,要么都是同一域名,一劳永逸,要么采用https协议+SameSite=none,或者不用新版浏览器,除此之外,好像也没有什么办法了(如果有,请告诉我-_-)。

解决方案 1.chrome设置

这种方式比较简单,手动禁用浏览器的限制功能,可参考文末链接【2】:

2.使用低版本浏览器

这也是一种解决方式,但是不推荐;

3.https协议 + SameSite=None

这主要依赖运维和后端处理了,但是这种方式在以后新版浏览器中可能会失效,因为过两年浏览器将全面禁止三方cookie,到时候么设置都不起作用了;

4.代理服务

如果上面的方式都不满足,可以考虑采用node作为请求-应答的中间层,大体设计如图:

图片描述


前端项目和代理服务位于同一个服务器,协议和域名一致,只是端口不同而已,为什么要这么设计呢,便于cookie共享, 因为cookie是不区分协议和端口的,因此只要域名(或者ip)一致,那么在同一台电脑上就可以读取同域名下的cookie
还需要说明的一点就是跨域问题是浏览器的安全策略,对于代理服务和后端服务来说就没有跨域一说了,而是进程间的通信。
接下来我们实现一个比较简单的三方cookie请求示例,其中各个服务的访问地址如下(都是本地模拟,因此代理和后端服务的ip一致,而真实情况往往不同):
前端项目: :8000
node代理服务: :8001
后端服务: :8002

示例演示与流程

图片描述

图片描述

1.登录验证

首先需要输入正确的用户信息获取cookie,这里我们使用iframe+postmessage的方式实现跨域登录请求,流程分为:
1.访问:8000,打开登陆界面,输入用户名和密码
2.点击登录,登录页面通过postMessage将登录信息发送给:8001页面,这个页面获取登录信息后调用:8001/login登录接口
3.请求到node代理服务后端,然后发起对真正的服务后端请求,然后将后端服务的响应返回给前端页面
4.如果校验成功,响应头会携带Set-Cookie信息,在:8001的域下写入cookie,同时:8000也会写入同样的cookie

2.cookie读取

图片描述


成功登录之后,在:8000和:8001都保存有cookie,实现了共享,可以通过document.cookie获取,如果服务端返回的cookie是httponly,这时可以在代理服务层将这个属性去掉就可以读取了。

3.查询数据

发起信息查询时,需要携带登陆成功后设置的cookie,这里就不通过iframe+postMessage的方式了,直接调用8001的接口服务,但是要注意一点的就是, 由于是跨域的脚本请求,因此是不会自动携带cookie信息的(即便是在客户端可以实现cookie共享) ,如果设置withcredentials相关属性,则还是三方cookie跨域的问题,是不容许携带cookie的,因此我们需要手动设置一个请求头 _cookie(cookie前面加了个下划线前缀) ,将cookie带上去。
8001上的代理获取到查询请求时,解析请求头的_cookie参数,然后重新设置请求头的cookie参数,再发送给真正的后端服务接口,这时候就可以实现cookie的校验了。

4.代码实现

文件结构图

图片描述


1.) 前端项目

<body> <iframe src="http://127.0.0.1:8001"></iframe> <!--代理服务首页,提供登录功能--> <div> <label>姓名:</label> <input type="text" /> <br> <label>密码:</label> <input type="password"> <br> <button>登录</button> </div> </body> <script type="text/javascript"> var proxyHost = "http://127.0.0.1:8001"; window.onload = function() { window.addEventListener("message", receiveMessage, false); document.querySelector('#btn-login').addEventListener('click', function login() { window.frames[0].postMessage({ // 发送跨域登录请求到iframe页面 url: '/login', payload: { name: document.querySelector('#name').value, pass: document.querySelector('#pass').value, } }, proxyHost); }, false); } function receiveMessage(event) { if (event.origin !== proxyHost) { return; } if (event.data.code === 0) { // 登录成功 fetchUser(); } } function fetchUser() { // 查询用户信息 $.ajax({ type : "POST", contentType: "application/json", url : proxyHost + "/fetchUser", headers: { _cookie: document.cookie, // 自定义请求头_cookie }, success : function(result) { console.log('fetchUser success:', result); }, error : function(e){ console.log('fetchUser error:', e); } }); } </script>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygjfz.html