赞
踩
浏览器的跨域问题以及解决方案
浅谈CSRF攻击方式
参考了上面的大神们的文章,以下是自己的总结。
跨域的产生来源于现代浏览器所通用的‘同源策略’,所谓同源策略,是指只有在地址的:
1. 协议名
2. 域名
3. 端口名
均一样的情况下,才允许访问相同的cookie、localStorage或是发送Ajax请求等等。若在不同源的情况下访问,就称为跨域。
跨域的访问会带来许多安全性的问题,比如,cookie一般用于状态控制,常用于存储登录的信息,如果允许跨域访问,那么别的网站只需要一段脚本就可以获取你的cookie,从而冒充你的身份去登录网站,造成非常大的安全问题,因此,现代浏览器均推行同源策略。
跨域一般有以下几种方式:
window.name
,再访问其他网页,就可以获取到window.name
属性,只要在其他网页监听window.name
属性的变化即可实现跨域的消息传递。window.domain
设置为相同,比如在http://aaa.next.com/index.html
中执行window.domain = 'next'
,在http://bbb.next.com/index.html
也执行window.domain = 'next'
,此时这两个不同的源之间就可以互相访问了。/* 子窗口 */
window.onmessage = function(e) {
if (e.origin !== 'http://bbb.com') return;
var payload = JSON.parse(e.data);
switch (payload.method) {
case 'set':
localStorage.setItem(payload.key, JSON.stringify(payload.data));
break;
case 'get':
var parent = window.parent;
var data = localStorage.getItem(payload.key);
parent.postMessage(data, 'http://aaa.com');
break;
case 'remove':
localStorage.removeItem(payload.key);
break;
}
};
/* 父窗口 */
var win = document.getElementsByTagName('iframe')[0].contentWindow;
var obj = { name: 'Jack' };
// 存入对象
win.postMessage(JSON.stringify({key: 'storage', method: 'set', data: obj}), 'http://bbb.com');
// 读取对象
win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
window.onmessage = function(e) {
if (e.origin != 'http://aaa.com') return;
// "Jack"
console.log(JSON.parse(e.data).name);
};
JSONP是通过在script标签中访问不同域的URL实现跨域:
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
这里的callback参数可以指定JSONP请求的回调,请求接收到的数据可以在回调函数的第一个参数中取到。
JSONP只能发送GET请求,作为跨域方式来说受到的限制比较多,如今适用性不是很广。
WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
由于这是一种特殊的跨域方式,在此不做详细说明。
CORS全称cross-origin resource sharing,意为跨站点资源共享,是w3c官方推荐的一种跨域方案,目前所有浏览器对其兼容性都表现良好,而且支持所有的请求方式,可以预见是未来最为广泛使用的跨域方案。
在支持CORS方案的浏览器中发送AJAX请求,请求地址为目标域的绝对路径时,请求头中会带有一个字段:withCredentials: true
,这个字段会让浏览器发送身份信息到服务端,如SSL、cookie等。与此同时,在服务端中设置响应头中的Access-Control-Allow-Origin: *
,则可以实现一个跨域请求。
注意:在实际使用中,最好对
Access-Control-Allow-Origin
进行指定域名的设置,如:Access-Control-Allow-Origin: www.test.com
。如果使用Access-Control-Allow-Origin: *
,则会允许所有来源进行跨域访问,这会带来比较大的安全问题。
使用cdn托管服务的时候,由于域名不同,加载某些静态资源的时候会出现跨域报错的情况,这个问题阿里云的帮助文档给出了解决方案:CDN支持cors(跨域)配置的步骤与注意事项
解决的方案其实也是使用CORS的原理,可以配置响应头字段Access-Control-Allow-Origin
(用于指定允许跨域的域名)与Access-Control-Allow-Methods
(指定允许跨域的请求类型)。
既然说到跨域,那就要说一下实现非法跨域导致的安全问题,CSRF攻击。
CSRF攻击,全称cross-site request forgery,即跨站点请求伪造。这篇文章对CSRF攻击做了详细的介绍:浅谈CSRF攻击方式。
下图简单的阐述了CSRF攻击的思想:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。