背景

新版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一致,而真实情况往往不同):
前端项目: http://127.0.0.1:8000
node代理服务: http://127.0.0.1:8001
后端服务: http://127.0.0.1:8002

示例演示与流程

1.登录验证

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

2.cookie读取


成功登录之后,在http://127.0.0.1:8000http://127.0.0.1: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" id="name" /><br><label>密码:</label><input type="password" id="pass"><br><button id="btn-login">登录</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>

2.) node代理服务

---`http://127.0.0.1:8001`---<script type="text/javascript">var appHost = "http://127.0.0.1:8000";function login(event) { // 调用代理服务登录接口$.ajax({type : "POST",contentType: "application/json",data: JSON.stringify(event.data.payload),url : "/login",success : function(result) {event.source.postMessage(result, event.origin); // 调用成功,发送返回数据给用户页面},error : function(e){event.source.postMessage(e, event.origin);}});}function receiveMessage(event) {if (event.origin !== appHost) {return;}if (event.data.url === '/login') {login(event);}}window.addEventListener("message", receiveMessage, false);</script>
---代理服务脚本---......const CORS_HEADER = {'Access-Control-Allow-Origin': 'http://127.0.0.1:8000','Access-Control-Allow-Headers': 'Content-Type, _cookie','Access-Control-Allow-Credentials': 'true',};......function sendProxyRequest(req, res) {const { method, headers, url } = req;const chunks = [];if(Object.hasOwnProperty.call(headers, '_cookie')) { // 包含自定义_cookie请求头,重新设置cookieheaders.cookie = headers._cookie;}req.on('data', (chunk) => {chunks.push(chunk);});req.on('end', () => {const request = http.request({ // 发送请求到后端服务host: '127.0.0.1',port: 8002,path:url,method,headers,}, (response) => {res.writeHead(response.statusCode, {...CORS_HEADER,...response.headers,});response.pipe(res);});request.end(Buffer.concat(chunks).toString());});}

3.) 后端服务

......const { method, headers, url } = req;const _method = method.toLowerCase();if (url === '/login' && _method === 'post') { // 登录验证const chunks = [];req.on('data', (chunk) => {chunks.push(chunk);});req.on('end', () => {const result = {code: -1,message: 'login fail',};const resHeaders = {'Content-Type': 'text/json',};const { name, pass } = JSON.parse(Buffer.concat(chunks).toString());if (name === '123' && pass === 'abc') { // 这里只校验123&abc这种情况result.code = 0;result.message = 'login success';resHeaders['Set-Cookie'] = `sid=abc; Max-Age=${getCookieExpires()};`; // 设置cookie}res.writeHead(200, resHeaders);res.end(JSON.stringify(result));});......return;}if (url === '/fetchUser' && _method === 'post') { // 用户信息查询if (req.headers.cookie === 'sid=abc') { // 校验cookieres.writeHead(200, {'Content-Type': 'text/json',});......} else {res.writeHead(401);res.end();}return;}

总结

第四种方法可以不修改后端服务,微调前端项目即可,因此对于现有项目改造成本较低,但是需要维护一个node服务代理,上面的示例演示了http协议,对于https站点,只需要稍微修改下node代理服务即可(https模块+根证书),最后再说一点,在前后端分离模式下,开发过程中遇到这样的问题,可以设置webapck的服务代理,具体可参考资料【4】,本文就讲到这里,大家如果有更好的解决方案,欢迎留言交流。

参考资料
【1】http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
【2】https://www.cnblogs.com/Summer6/p/11671204.html
【3】https://juejin.im/post/6844904128557105166
【4】https://www.yuque.com/mdtvv0/myv5bw/es2oeo

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

  1. COOKIE伪造登录网站后台

    1.关于XSS(跨站脚本攻击)和CSRF(跨站请求伪造)的知识,xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从 ...

  2. 在chrome中设置禁止访问的网站

    如何在chrome中禁止访问某个网站: 点击右上角,一竖排点那个按钮: 2.选择"设置": 3.左边选择"隐私与安全设置": 4.选择网站设置最左边的小箭头: ...

  3. Chrome清除某一个网站的Cookie

    文章目录 Chrome清除某一个网站的Cookie 打开Chrome, 进网站设置 你懂的 右上角,输入想要删除Cookie的网站的网址,即可搜索出相关的全部Cookie内容. 太简单了 Chrome ...

  4. Cookie登录爬取实战:Python 利用urllib库的cookie实现网站登录并抓取

    1 环境:Python 3 +urllib库 实战网站:http://www.mjzcnd.com/  梅江之春论坛网站 2 背景: 现在许多网站都需要登录后才能访问某个页面,在登陆之前,我们是没有权 ...

  5. 当浏览器全面禁用三方 Cookie

    关注公众号 前端开发博客,领27本电子书 回复加群,自助秒进前端群 苹果公司前不久对 Safari 浏览器进行一次重大更新,这次更新完全禁用了第三方  Cookie,这意味着,默认情况下,各大广告商或 ...

  6. fetch 自动加cookie_如何在shell中动态获取chrome浏览器的cookie信息

    0. 背景 在工作的时候,经常要接触一些办公系统,在网页上通过机械化的操作,来完成一个简单的功能,比如某台主机权限的申请,通过一套操作一下,大概7.8个步骤,花费30秒的时间,虽然不长,但是要脱离终端 ...

  7. 使用Cookies登录网站--登录豆瓣网站

    使用Cookies登录网站–登录豆瓣网站 首先打开豆瓣的首页,输入用户名和密码并单击"登录豆瓣",显示的结果验证打开的是已经登录的个人主页,说明已经成功地使用Cookies登录豆瓣 ...

  8. java ee 系统视频_更好的网站登录系统,EE协作登录系统

    java ee 系统视频 Preface 前言 This article introduces an authentication and authorization system for a web ...

  9. Python爬虫——Cookie模拟登录

    文章目录 Python爬虫--Cookie模拟登录 1.Cookie模拟登录 2.Handler处理器 Python爬虫--Cookie模拟登录 1.Cookie模拟登录 现在很多网站需要用户成功登录 ...

最新文章

  1. Linux常用命令和常见问题解决------第一章
  2. 动手学无人驾驶(7):车道线检测
  3. springclould项目启动报错Could not resolve placeholder
  4. github出现Your account has been flagged.导致账号无法公开的解决办法
  5. python读取yaml文件
  6. 螺杆泵matlab,基于Matlab与VC++混合编程的螺杆泵转子型线设计
  7. ubuntu下C语言编程的注意点
  8. 算法知识点——(3)监督学习——逻辑回归与线性回归
  9. Zabbix2.4.X_监控SNMP
  10. 阿里云周明:因云而生的基础设施
  11. MQTT再学习 -- 搭建MQTT服务器及测试
  12. 交管123缴费显示代理服务器异常,交管12123服务异常怎么回事?交管12123网络请求失败怎么办...
  13. 计算机的同步操作与异步操作的概念,运城计算机同步与异步的概念和应用方法...
  14. 转:Windows XP系统中如何屏蔽 Ctrl+Alt+Del、Alt+Tab以及Ctrl+Esc键序列
  15. 用最通俗的语言讲一讲,什么是阻抗匹配?
  16. 如何解决高度塌陷【超全面】
  17. OCJP(1Z0-851) 模拟题分析(三)
  18. Linux的一些快捷键
  19. android仿小米指南针
  20. 夏培肃对计算机科学发影响,夏培肃:我国计算机领域的先驱者

热门文章

  1. ubuntu安装chrome driver
  2. python作业高级FTP(第八周)
  3. 编写高质量代码:改善Java的151个建议四(基本类型)21-30
  4. 三)mybatis 二级缓存,整合ehcache
  5. 【第四周作业】参加项目开发之后的一些体会
  6. MyEclipse JAVA提示信息配置
  7. C# 生成私钥和公钥
  8. Teams的manifest文件开始支持多语言
  9. 怎么做mysql查询系统_mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?...
  10. 矿难让显卡压了那么多货咋办?NV如是说