同源策略与跨域

前言:最近业务上前端同学多次联系说访问腾讯云cos资源的时候因为跨域的问题访问不到。大致看了下腾讯云关于设置跨域访问的教程,按照前端同学给的域名等选项就给配了,而且测试下来也是好的。但是呢一直不知道什么是跨域这里就做一个简单的学习记录。

一、同源策略

        同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也是最基本的安全功能。同源策略会阻止一个域的javascrip脚本和另一个域的内容进行交互,是用于隔离潜在恶意文件的关键安全机制;关于这一点我们后面会举例说明。如果缺少了同源策略浏览器的安全使用会受到很大的影响。可以说web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

1、同源的定义

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

如下表给出了相对http://www.example.com/dir/page.html的同源检测示例:

URL 结果 原因
http://www.example.com/dir2/other.html 成功 协议、域名、端口相同
http://www.example.com/dir/inner/another.html 成功 协议、域名、端口相同
https://www.example.com/secure.html 失败 协议不同 ( HTTPS )
http://www.example.com:81/dir/etc.html 失败 端口不同 ( 81 )
http://news.example.com/dir/other.html 失败 域名不同

同源策略目的就是为了保证用户信息的安全,防止恶意的网站窃取用户数据。如果网页之间不满足“同源”的要求,那么它们之间:

(1)不能共享Cookie、LocalStorage、IndexDB
(2)不能获取DOM
(3)AJAX请求不能发送

2、同源策略作用举例

        下面举一个例子说明针对接口的请求没有同源策略会怎么样?

        cookie大家应该知道,一般用来处理登录等场景,目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录,服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中,服务端就能知道这个用户已经登录过了。知道这个之后,我们来看场景:
1.某11到了,于是打开了买买买网站www.maimaimai.com,然后登录成功,然后准备一番剁手操作。
2.期间你的好朋友突然给你发了一个你懂得的网站链接www.nidongde.com,一脸yin笑地跟你说:“你懂的”,你毫不犹豫打开了。
3.你饶有兴致地浏览着www.nidongde.com!由于没有同源策略的限制,它向www.maimaimai.com发起了请求!前面我们说过“服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”,这样一来,这个不法网站就相当于登录了你的账号,可以为所欲为了!如果这不是一个买买买账号,而是你的银行账号,那……
这个过程就是就是CRFS(跨站请求伪造)攻击了!!参见 这里

       显然,同源策略是非常重要的。否则网站站长、广告联盟、流量统计商、xss黑客,随便哪个人都将无障碍的获取私密信息,例如各个网站的Cookie、email的邮件内容、OA页面的内容、QQ空间里设置为隐私的照片等。

        

3、同源策略的让步

    几乎任何时候安全性和便利性都是负相关的,追求安全性的时候肯定会对便利性造成负面影响。同样,同源策略提升了web前端的安全性,但是却牺牲了web扩展上的灵活性。所以,现代浏览器在安全性可可用性之间选择了一个平衡点。即在遵循同源策略的基础上,选择性的为同源策略“开放了后门”。例如img、script、style等变迁都允许跨域引用资源,严格来说这都是不符合同源要求的。只不过这里只是引用这些资源,并不能读取到这些资源的内容。因此浏览器降低了一点点的安全性,缺大大提升了网站布置的灵活性。

二、跨域问题

        由于同源策略存在带来的问题就是跨域问题了。

1、跨域访问限制的流程

同源策略,它是由Netscape提出的一个著名的安全策略。
所有支持JavaScript 的浏览器都会使用这个策略。
所谓同源是指,域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面
当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,
即检查是否同源,只有和百度同源的脚本才会被执行。 [1]
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

如上图所示,跨域访问限制的作用流程大致如下:

1、 浏览器发送跨域请求
2、 接收response数据
3、 检查响应头
(1)如果响应头中没有允许跨域访问的配置,则不加载,并报出响应异常
(2)如果响应头中有允许跨域访问的设置,正常加载数据

即,同源策略并不是浏览器不让请求发出去、或者后端拒绝返回数据。实际情况是请求正常发出去了,后端也正常相应了,只不过数据到了浏览器后浏览器不去作用加载而是丢弃了。

三、跨域问题的解决

1、JSONP:以后涉及到在说。

2、CORS(Cross-Origin Resource Sharing)跨域资源共享机制

        简称为跨域访问,允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器要求版本 IE10 或以上。

        整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户无感知。

        因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,即可跨源通信。

(1)CORS使用场景

        用户在使用浏览器的情况下会使用到 CORS,因为控制访问权限的是浏览器而非服务器。因此使用其它客户端的时候无需关心任何跨域问题

        对于我们遇到的问题来说,CORS 的主要应用是实现在浏览器端使用 AJAX 直接访问 COS 的数据或上传、下载数据,而无需通过用户本身的应用服务器中转。

(2)CORS原理:

我们看一眼之前跨域报错的信息:

 浏览器判断后端有没有返回CORS头(Access-Control-Allow-Origin),发现没有就认为后端不允许跨域,即认为返回的数据不可靠。

所以只要后端能够返回浏览器需要的请求头,即可跨域(相应数据不会被同源策略抛弃)。

上面是表面原理,底层原理比较复杂。

浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求。

简单请求

只要同时满足以下两大条件,就属于简单请求。:

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin.

刚才说过,CORS需要客户端和服务端同时支持。上面这个小操作,算是客户端的支持行为(IE10以下不行)。

Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。

如果服务器允许跨域,需要在返回的响应头中携带下面信息(算是服务端的支持):

  • Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*(代表任意域名)。上图CORS策略配置的允许跨域请求来源是“*”,表示全部域名都允许。
  • Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true

有关cookie:

要想操作cookie,需要满足3个条件:

  • 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
  • 浏览器发起ajax需要指定withCredentials 为true
  • 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名

这样一来,前后端都支持跨域了,那就跨吧。

注意:

(1)测试截图是根据腾讯云手册的设置实例来的,这里 

(2)关于web网页的部署,参见 草稿“Linux下的web服务器搭建”。

(3)另外配置web服务器的时候要注意安全组规则的设置;另外可以通过调整COS的跨域策略对比能否成功跨域在请求和相应方面的差异。

猜你喜欢

转载自blog.csdn.net/mijichui2153/article/details/121456386