同源跨域二三事:从同源策略到 JSONP 技术略解

三问同源策略

(一)什么是同源策略?

同源策略是浏览器因安全性需要而诞生的沙盒机制中的其中一个策略。
所谓同源,就是要三同:同协议,同域名,同端口号。其中任意一个不相同,都不能称之为同源。非同源网站间 JavaScript 脚本的行为受到了严格的限制,以提供必要的安全性。

(二)同源策略限制了什么?

JavaScript 不能

  1. 获取非同源网站的 Cookie;
  2. 访问非同源网站的 DOM;
  3. 向非同源网站发出 AJAX 请求。

(三)如果没有同源策略,Web 应用的安全性会受到哪些挑战?

举几个例子来进行说明。
首先,如果没有同源策略,那么任意网站都可以获取对方的 Cookie 值。Cookie 是用来进行会话管理的工具。把 Cookie 比作一个令牌,在用户拿着令牌,道出名字和密码验证通过之后,服务器就记下了令牌的模样,下次再来,只需出示令牌,服务器便认你是之前那个人。如果 Cookie 不受同源策略的保护,那么恶意网站就能够夺了你的令牌,到你的后花园中随意走动,不受限制。
我们知道有些标签是不受同源策略的限制的,比如 iframe 标签,img 标签,script 标签等。如果在恶意网站里嵌入 iframe,设置 src 属性值为淘宝网地址,那么只要你登录了淘宝,点开了这个网站,那么 iframe 就带着你的 Cookie 也登录了淘宝。此时,如果恶意网站能访问 iframe 的 DOM,那你的隐私信息就能轻易地被一览无余。

同源跨域二三事:从同源策略到 JSONP 技术略解

需要跨域怎么办?

需要跨域怎么办(一)——JSONP 的解决方式

由前所述,script 等一众具有 src 属性的标签是不受同源策略的限制的。所以 JSONP 就借着这个特性被用来进行非同源网站之间的 JSON 信息的共享。
假如 A 网站编写了一个使用了 JSONP 技术的 API 接口,链接为 www.a.com/api/get-user-info,当其他非同源网站 B 需要使用这个接口时,它只需要在 html 中写下这样的代码。

<script>
    function dealWithJSON(json) {
        # 以下省略
    }
</script>
<script src="www.a.com/api/get-user-info?callback=dealWithJSON"></script>

我们不妨假设 B 需要的 JSON 数据如下。

{
    username: 'test',
    uid: 2233221,
    is_vip: true,
    balance: 1111111
}

A 网站会将这条 JSON 数据放到通过 callback 传来的函数的参数中,一并返回给 B 网站。此时这个函数就连同参数一起嵌入了 B 网站的 script 标签中,具体如下。

<!-- 以上省略 -->
<script>
    function dealWithJSON(json) {
        # 以下省略
    }
</script>
<script>
    dealWithJSON(
        {
            username: 'test',
            uid: 2233221,
            is_vip: true,
            balance: 1111111
        }
    );
</script>
<!-- 以下省略 -->

由于已经提前定义好了处理 JSON 数据的函数,所以 B 网站可以根据需要处理取出来的数据。这也就实现了跨域资源共享的需求。
然而,这样的方式虽然在同源策略的限制下实现了跨域资源共享,但也会由于一些纰漏出现安全性问题:JSON 劫持(此处暂时不表)。

需要跨域怎么办(二)——CORS 的解决方式

CORS 与 JSONP 目的相同,但比 JSONP 更强大。JSONP 只支持 GET 请求,而 CORS 支持所有请求。对于 CORS,阮一峰老师的跨域资源共享 CORS 详解一文已经讲得非常清楚透彻,需要进一步了解的朋友可以参看这篇文章,就不在这里重复造轮子了(逃)。

后记

写这篇文章的初衷其实是在学习 Web 安全的时候碰到了这个概念,当时对同源跨域是一头雾水,感觉太过抽象,不好理解。查阅了多篇文章和书籍后才对这个概念有了一点了解。就如标题里写的一样,本文是略解一二,如果有错误不准确之处请向我砸来评论!此致,敬礼(不是)。

相关推荐