首页 > 其他 > 详细

以三个视角分析跨域解决方案

时间:2021-05-28 22:37:44      阅读:20      评论:0      收藏:0      [点我收藏+]

1.什么是域

域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。

有一种简明的说法来解释跨域:跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。

2.跨域的产生原因

根本原因是浏览器同源策略的约定,有Netscape公司在1995年引入浏览器,它是浏览器最核心也是最基本的安全功能,如果缺少同源策略,浏览器很容易受到XSS,CSFR等攻击。

同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。协议、域名(主域,子域)、端口有任何一项不同都会产生跨域

延伸:

2.1什么是XSS(Cross Site Scripting),因为缩写与层叠样式表相同,所以命名为XSS

XSS中文名是跨站脚本攻击,XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

2.2什么是CSFR(Cross-site request forgery),跨站请求伪造

一般来说就是以你的名义发送邮件,发消息,盗取你的账号,在受害者不知情的情况下,以受害者名义伪造请求发送给受攻击站点,从而在受害者并未授权的情况下执行受害者权限下的各种操作。

攻击过程
  • 1.用户user01通过浏览器访问正常网站A,输入用户名和密码请求登录验证
  • 2.登录验证通过后,网站A保存user01的session,并将对应的cookie返回给user01的浏览器。这样user01就可以在网站A执行自身权限下的各种请求(操作),比如取钱,发表文章,发表评论等
  • 3.user01在未退出网站A的时候,在同一浏览器,点击访问了恶意网站B(钓鱼网站),此时user02拿到user01的认证信息或者登录状态
  • 4.网站B是user02创建的,user02清楚的知道网站A的工作模式,网站B通过攻击性代码访问网站A(携带的是user01的cookie),执行某些并非user01授意的操作。
  • 5.网站A并不知道这个恶意请求是从网站B发出的,因此,就会根据user01在网站A中具备的相关权限,执行权限下的各种操作。这样,就在user01不知情的情况下,user02假冒了user01,执行了具备user01用户身份才可以执行的操作

3.跨域的实际解决方案

3.1最实用,CORS(跨域资源共享)

原理:

简单跨域请求,在服务端设置Access-Control-Allow-Origin即可,前端无需设置。

Node的实现代码:

const express = require(‘express‘);
const app = express();
app.use((req, res, next) => {
    ////允许所有的接口跨域访问,允许任意的 主机 来访问我。
    res.header("Access-Control-Allow-Origin", "*");
    next();
});

非简单跨域请求,在正式通信之前,增加一次HTTP查询请求称为预检,需要在请求头添加的代码

Access-Control-Allow-Credentials: <可选> true表示允许发送cookies 
Access-Control-Expose-Headers: <可选> 调用getResponseHeader()可以获取的其它字段

为什么最实用?支持所有的HTTP请求,不需要前端配置,是最主流的结局方案。存在的问题是IE5、6、7不支持,但是微软公司表示,从明年6月15日开始,IE浏览器将正式退出历史的舞台

Extend:什么是Cookie

Cookie 是一些数据, 存储于你电脑上的文本文件中。

当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。

Cookie 的作用就是用于解决 "如何记录客户端的用户信息":

  • 当用户访问 web 页面时,他的名字可以记录在 cookie 中。
  • 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。

Cookie 以名/值对形式存储,如下所示:

username = xiaoming

当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。

3.2最古老,JSONP

浏览器不允许跨域请求资源,但允许跨域群请求文件。JSONP主要是利用script的src标签链接外部js文件,以函数调用的形式,将要传递的数据作为函数参数进行传递。需要前后端的配合不仅工作效率低,而且只支持get请求

页面代码:
<script>
    var script = document.createElement(‘script‘);
    script.type = ‘text/javascript‘;

    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = ‘http://www.domain2.com:8080/login?user=admin&callback=handleCallback‘;
    document.head.appendChild(script);

    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>


服务器代码:
handleCallback({"success": true, "user": "admin"})


优点是适用于所有浏览器,实现简单,缺点是只能使用get请求,比较局限,现在使用频率比较低。

3.3最新颖

window.postMessage() 是HTML5的一个接口,专注实现不同窗口不同页面的跨域通讯(即是有点也是缺点)。postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递
  • 上面三个场景的跨域数据传递

用法:postMessage(data,origin)方法接受两个参数:

  • data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
  • origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
页面1
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById(‘iframe‘);
    iframe.onload = function() {
        var data = {
            name: ‘aym‘
        };
        // 向domain2传送跨域数据
        iframe.contentWindow.postMessage(JSON.stringify(data), ‘http://www.domain2.com‘);
    };

    // 接受domain2返回数据
    window.addEventListener(‘message‘, function(e) {
        alert(‘data from domain2 ---> ‘ + e.data);
    }, false);
</script>

页面2
<script>
    //本文案例代码部分借鉴:https://www.imooc.com/article/291931
    // 接收domain1的数据
    window.addEventListener(‘message‘, function(e) {
        alert(‘data from domain1 ---> ‘ + e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;

            // 处理后再发回domain1
            window.parent.postMessage(JSON.stringify(data), ‘http://www.domain1.com‘);
        }
    }, false);
</script>

以三个视角分析跨域解决方案

原文:https://www.cnblogs.com/Code-Is-Fun/p/14823731.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!