同源政策(same-origin policy)

2024-04-12 21:32
文章标签 origin policy 同源 政策

本文主要是介绍同源政策(same-origin policy),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

浏览器同源政策(Same-origin policy) 是浏览器安全的基石。它是前端开发人员必须要理解的一个知识点,也是后面各种实现跨域资源访问方式学习的基础。在接触这方面的知识时个人思考很多,在此记录一下。只能看作是个人的当前理解,并不代表一定准确,如果有误,希望指出。

1. 同源的定义

学习同源政策之前我们先明确一下同源的概念。在浏览器中,如果两个页面(请求)拥有相同的协议、域名和端口,那么这两个页面就属于同一个源(origin)。其中只要有其中一个不相同,就是不同源。例如网址 http://www.tkop.com/dirname/home 与下列各网址的同源关系分析如下。

  1. http://www.tkop.com/dirname3/admin (同源)
  2. http://www.yangchen.com/dirname/home (不同源,域名不相同)
  3. http://v1.www.tkop.com/dirname/home (不同源,域名不相同)
  4. http://www.tkop.com:81/dirname/home (不同源,端口号不相同)
  5. https://www.tkop.com/dirname/home (不同源,通信协议不同)

2. 同源政策对 ajax 请求的限制

同源政策由 Netscape 公司于 1995 年提出,其目的是为了保证用户信息的安全,防止恶意网站窃取数据。最初的同源政策是指 A 网站在客户端设置的 Cookie 在 B 网站(非同源页面)不能访问。

但是随着互联网的发展,同源政策也越来越严格(限制越来越多)。其中还规定了在不同源的情况下,无法向非同源地址发送 ajax 请求(ajax 请求限制),如果发请求,浏览器就会报错。通俗地讲就是 ajax 只能向自己地服务器发送请求。例如现有 A、B 两网站(服务器),A 网站中的页面只能向 A 服务器发送 ajax 请求,B 网站中的页面只能向 B 服务器发送 ajax 请求。但是浏览器是不允许 A 网站中的页面向 B 服务器发送 ajax 请求的(其实是允许的,不过拒绝接受处理响应),同理,也不允许 B 网站中的页面向 A 服务器发送 ajax 请求。 以上都是理论,下面我演示一下同源政策的 ajax 限制。

1、首先服务器端创建两个监听不同端口的服务。注意 A 监听 3000 端口,B 监听 3001 端口,两个服务不同源。

// 引入express框架
const express = require('express');
// 引入路径处理模块
const path = require('path');// 创建 A、B 两个服务
const A = express();
const B = express();
// 开放两服务器的静态文件
A.use(express.static(path.join(__dirname, 'publicA')));
// 虽然只是演示,但为让大家不搞混淆还是将静态文件放到两个不同的文件夹
B.use(express.static(path.join(__dirname, 'publicB')));// B服务的一个get请求处理路由
B.get('/example', (req, res) => {res.send('来自B的响应');
});// 分别监听不同端口(不同源)
A.listen(3000);
B.listen(3001);
console.log('服务已开启,需访问A、B服务器可访问本机不同端口');

2、创建服务器端服务后在 A 服务页面 aaa.html 中向 B 服务器发送 ajax 请求。这里为了方便没有使用 jquery 的 $.ajax() 发送请求或者原生 js 发送请求,而是使用了前面自己封装的 ajax() 函数。

在这里插入图片描述
3、访问地址 http://localhost:3000/aaa.html ,即访问 A 浏览器的静态页面。再向 B 浏览器发送 ajax 请求,查看浏览器对请求的处理和响应的处理。可以看到浏览器首先会出现如下报错信息。

在这里插入图片描述
使用我蹩脚的英语水平翻译过来就是:请求资源头信息中不存在 “Access-Control-Allow-Origin” 字段信息。从源 “http://localhost:3000” 访问 “http://localhost:3001” 的 ajax 请求已被同源政策阻止。

看看这次请求的请求头信息和响应头信息,如下图所示:

在这里插入图片描述
为了对比我们可以在 B 网站的 bbb.html 页面中发送一个相同的 ajax 请求(没有跨域),我将它的请求信息截图如下,方便与上图对比:

在这里插入图片描述
通过上图,比较一下跨域和不跨域的情况下请求报文和响应报文中头信息的一些字段的值的差异。

  • 跨域请求的请求头信息中的 Sec-Fetch-Site: same-site ,而非跨域请求的请求头信息中的 Sec-Fetch-Site: same-origin 。所以这是表示这次请求是否属于跨域请求。

  • 在跨域请求的请求头信息中则增加了 Origin 字段,值为发出请求的页面(aaa 的脚本)的协议、地址和端口

  • 然后比较一下响应头信息,发现它们一模一样,其实这算是同源政策的本质的一个体现。同源政策本质上是浏览器客户端为维护用户数据安全而设定的,与服务器端没有太大的联系(个人觉得唯一联系可能就是服务器可以提供是否允许跨域请求数据或者访问 cookie 等权限的验证信息供浏览器进行验证),这也是为什么我们将其称为浏览器的同源政策即无论是否涉及跨域,浏览器按照要求正常发出请求,服务器接收请求并给出响应,浏览器也能接收到响应。但是浏览器根据同源政策有权决定是否将响应数交由页面脚本处理(或者报错)

  • 为什么我敢给出上面的结论呢?你可以将注意力放在响应头信息中的 Content-Length 字段。这个字段显示的正是服务器响应内容的字节长度,例如上面的响应是字符串 “来自B的响应”,英文字母 B 是 1 个字节,每个汉字 3 个字节。这也就说明了即使跨域访问也确实可以接收到服务器的响应信息。

上面我们已经清楚了同源政策对 ajax 的限制,但是浏览器的同源政策的限制不止这个。总结如下:

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求无法发送。

在此我的笔记只会涉及 Cookie 无法获取和 ajax 请求无法发送的问题,其他的不会进行学习记录。不知道你是否已经了解学习过有关 Cookie 和 Session 的相关知识,都学到跨域资源共享了我觉得应该是没问题了。

3. 小对话(sessions)

为了更加深刻地理解浏览器地同源政策,我自己参考自己地思考编了下面一小段会话。A 代表 A 服务器,B 代表 B 服务器,aaa 代表上面的 aaa.html 页面(A 服务器的页面),bbb 代表 B 服务器上的 bbb.html 页面(B服务器上的页面,假设是登录页面),小刘代表浏览器。并假设 B 是我现在使用的 CSND 服务器,A 是某恶意网站。

用户在浏览器输入 B 网站首页地址。。。

用户:小刘你去跟 B 要一下它们首页的数据。

小刘跟 B 要了数据并将登录(bbb)页面渲染展示给用户。。。用户输入登录信息。。。

用户:登录账号密码填好了,小刘你让 B 瞧瞧看看我能不能登录。

B 验证用户输入的账号密码。。。确认通过。。。

B:小刘你跟用户说他登录成功了(响应数据),还有这是他的登录证明(Cookie),保存好,下次他跟我要东西(发请求)的时候带上它。我是记不住他的。

用户没有退出登录,又在浏览器输入A 网站的访问地址并请求到了 aaa 页面。。。

如果没有同源政策 aaa(其中添加的恶意脚本)可以怎么样?

aaa:小刘你去跟 B 要一下用户的用户的电话号码。

小刘此时并未察觉 aaa 不是 B 网站的页面脚本。小刘没管那么多就带着 B 给 Cookie 跟 B 要用户的电话号码。。。

小刘:B 哥这是你上次给用户的登陆证,他现在要看看电话号码,你给我吧。

B 看了看 Cookie 确实是自己发出去的,并根据 Cookie 里面的信息比如用户 ID 找到了用户的号码,并将它给了小刘。

小刘:aaa 这是你要的东西,不用谢。
aaa:小刘你再去跟 B 说我要删掉所有的博客内容并注销账户。

小刘此时还是未察觉 aaa 不是 B 网站的页面脚本,又带着 Cookie 过去了

B:什么!!!他要注销?好吧,登录证明(Cookie)你都带过来那证明他确实登录过了也有权进行这些操作了,那注销掉吧。

看到这我们发现如果没有同源政策会出现两个问题:

  • 浏览器不会根据是否同源去判断是否携带 B 给用户设置的 Cookie 来对 B 进行访问(或者说判断 aaa 是否有权访问使用这份 Cookie),导致服务器误判。
  • 浏览器也不会根据是否同源判断脚本是否有权力获得服务器响应的数据。

根据这两点我们大概也就理解了同源政策的本质。如果有同源政策那上面的对话会变成怎么样呢?

aaa:小刘你去跟 B 要一下用户的用户的电话号码。

小刘看了看 aaa 的请求地址中的协议、IP 和端口。嗯?发现它和 B 不是同源的,也不知 B 哥允许它请求数据不。将它记在笔记本(Origin)上先。但是 B 哥上次给的登录证(Cookie)就默认不带了。

小刘:B 哥有个哥们想向你要电话号码。

B 看看小刘没带登录证说明他那哥们没登陆过呀,给你返回些没登录过的数据吧(叫他先登录)。

B:小刘这是你可以给他的数据,还有这是能够得到这些数据的白名单(Access-Control-Allow-Origin),还有这是我能接受他们(白名单内的人)的请求方式(Access-Control-Allow-Methods),如果他们在名单内就给他们数据吧,你自己决定。

小刘拿到哪份名单发现 aaa 的 IP 和协议虽然一样但是端口不一样。。。。当然 B 哥也许没有给他那份名单(例如我们的示例),那连给都没给说明不允许跨域了。

小刘:aaa 对不起呀,B 并不允许你获取他的数据。他提供的数据我不能给你(报错)。

上面的某些内容涉及到了跨域资源共享的部分知识和有关跨域 Cookie 携带问题。后面会详细介绍(相关笔记写完贴链接)。反正上面就大致体现出了同源策略的重要性,并不是说他可以解决掉所有问题,使网站绝对安全(谁都做不到,不知道你有没有看过没有绝对安全的系统这个电影),例如恶意网页可以伪造Origin头信息,绕过服务端对Origin头的检查等。

下面是我在一个有关文章下面看到的一个有关评论,觉得不错所以截了下来。

在这里插入图片描述
以上就是我对浏览器同源政策的理解,如果对你有帮助希望可以给我点个赞(鼓励一下不断进行知识输出的人儿)。后面解决一下跨域资源访问的问题,涉及的知识有 JSONP、CORS 和 WebSocket

这篇关于同源政策(same-origin policy)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/898293

相关文章

访问controller404:The origin server did not find a current representation for the target resource

ider build->rebuild project。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。由于 Rebuild 的目标只有 Project,所以 Rebuild 每次花的时间会比较长。 参考:资料

Google play最新政策更新和重要提醒

我们都知道,谷歌会定期更新其政策,而政策的变更通常对开发者及其团队的要求会更为严格,也会增加应用上架的一些限制条件,以此提高应用在谷歌商店的质量。 一起来看看Google play最近的一些政策更新和需要注意的地方。 新政策要求 对于提供金融产品和服务、健康服务、VPN、政府相关服务的开发者,需要注册为“企业”开发者账号才能提审上架应用。 Google play这个举措主要

第十五章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(二)

文章目录 第十五章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(二)`<method>``<request>``<response>` 第十五章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(二) <method> <method> 元素将策略与父 <service> 元素指定的 Web 服务或客户端内的特定 Web 方法

解决Vue请求 ‘No 'Access-Control-Allow-Origin' header is present on the requested resource’错误

如果我们用VueResouce直接请求,这样写(以豆瓣api为例): this.$http.get('https://api.douban.com//v2/movie/top250').then((response) => {this.movie = response.data;console.log(this.movie); }); 就会报错: 因为这是一个跨域的请求,不能直接

国内外网络安全政策动态(2024年7月)

国内网安政策动态 1.《网络安全 物联网安全与隐私 家庭物联网指南》正式发布 7月1日,我国牵头提出的国际标准ISO/IEC 27403:2024《网络安全 物联网安全与隐私 家庭物联网指南》(Cybersecurity – IoT security and privacy – Guidelines for IoT-domotics)正式发布。 1.《网络安全 物联网安全与隐私 家庭物联

【科研绘图】【3D轨线图】:附Origin详细画图流程

目录 No.1 理解3D轨线图 No.2 画图流程 1 导入数据并绘图 2 设置绘图细节 3 设置坐标轴 4 效果图 No.1 理解3D轨线图 3D轨线图,是指在三维坐标系中,通过连续的点或线段连接而成的图形,用于表示一个或多个物体在三维空间中的运动路径。这些路径可以是直线、曲线或者更复杂的轨迹,它们随时间的变化而变化,从而展示物体的动态行为。 No.2 画图

强化学习实践(二):Dynamic Programming(Value \ Policy Iteration)

强化学习实践(二):Dynamic Programming(Value \ Policy Iteration) 伪代码Value IterationPolicy IterationTruncated Policy Iteration 代码项目地址 伪代码 具体的理解可以看理论学习篇,以及代码中的注释,以及赵老师原著 Value Iteration Policy Itera

Origin制图——点线图转换为叠层图

1.当我们绘制点线图的时候我们发现,当数据差距较大或者差距较小的时候,绘制的图会很难看,如下图所示。怎么样才能更好的表达图的意思并且好看。那么接下来分享一下最新学习的叠层图教学。 2.首先我们还是按照点线图的画图方法,将点线图优化。简单优化后的数据图如下所示。可以看到这是很紧密的,也十分的不好看,因此我们需要对数据进行分层。 3.点击右上角的图层分层。原始是2行2列,我们只需要4行1列(4个

云端青柚UZ:顺势而为,响应政策,坐享最大“红利”

云端青柚项目自上线以来,引起了坊间的无数热议。很多相关用户都对云端青柚的迅速崛起保持着极大的兴趣和关注,业内专家与资深人士也对这个项目持有十分积极的评价。 究其原因,很大程度上是因为云端青柚是顺应了发展趋势,是基于“农业产业化”与“区块链应用落地化”这两大背景与趋势而发展出的优质项目。 在区块链领域摸爬滚打的人,往往把一句话奉为圭臬:“站在风口上,猪都会飞”。诚然,这句话有它偏激极端的一面,但

mysql密码策略修改(password does not satisfy the current policy requirements)

1.查看当前策略.SHOW VARIABLES LIKE 'validate_password%'; 2.修改策略 等级改为最低:set global validate_password_policy=LOW; 长度改为6:set global validate_password_length=6;