xmlhttprequest 跨域_跨域资源共享(CORS)安全性

跨域资源共享(CORS)安全性

背景

提起浏览器的同源策略,大家都很熟悉。不同域的客户端脚本不能读写对方的资源。但是实践中有一些场景需要跨域的读写,所以出现了一些hack的方式来跨域。比如在同域内做一个代理,JSON-P等。但这些方式都存在缺陷,无法完美的实现跨域读写。所以在XMLHttpRequest v2标准下,提出了CORS(Cross Origin Resourse-Sharing)的模型,试图提供安全方便的跨域读写资源。目前主流浏览器均支持CORS。

技术原理

CORS定义了两种跨域请求,简单跨域请求和非简单跨域请求。当一个跨域请求发送简单跨域请求包括:请求方法为HEAD,GET,POST;请求头只有4个字段,Accept,Accept-Language,Content-Language,Last-Event-ID;如果设置了Content-Type,则其值只能是application/x-www-form-urlencoded,multipart/form-data,text/plain。说起来比较别扭,简单的意思就是设置了一个白名单,符合这个条件的才是简单请求。其他不符合的都是非简单请求。

之所以有这个分类是因为浏览器对简单请求非简单请求的处理机制是不一样的。当我们需要发送一个跨域请求的时候,浏览器会首先检查这个请求,如果它符合上面所述的简单跨域请求,浏览器就会立刻发送这个请求。如果浏览器检查之后发现这是一个非简单请求,比如请求头含有X-Forwarded-For字段。这时候浏览器不会马上发送这个请求,而是有一个preflight,跟服务器验证的过程。浏览器先发送一个options方法的预检请求。如果预检通过,则发送这个请求,否则就不拒绝发送这个跨域请求。

下面详细分析一下实现安全跨域请求的控制方式。先看一下非简单请求的预检过程。

非简单请求

浏览器先发送一个options方法的请求。带有如下字段:

- Origin: 普通的HTTP请求也会带有,在CORS中专门作为Origin信息供后端比对,表明来源域。
- Access-Control-Request-Method: 接下来请求的方法,例如PUT, DELETE等等
- Access-Control-Request-Headers: 自定义的头部,所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中

服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

会返回对应对的字段

  • Access-Control-Allow-Origin:
  • Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次“预检”请求。
  • Access-Control-Allow-Headers:

如果服务器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获

一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

为什么要预检?

这是为了防止这些新增的请求,对传统的没有 CORS 支持的服务器形成压力,给服务器一个提前拒绝的机会,这样可以防止服务器大量收到DELETE和PUT请求,这些传统的表单不可能跨域发出的请求。

简单请求

简单请求前面讲过是直接发送,只是多加一个origin字段表明跨域请求的来源

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

  • Access-Control-Allow-Origin: 允许跨域访问的域,可以是一个域的列表,也可以是通配符"*"。这里要注意Origin规则只对域名有效,并不会对子目录有效。即http://foo.example/subdir/ 是无效的。但是不同子域名需要分开设置,这里的规则可以参照同源策略
  • Access-Control-Allow-Credentials: 是否允许请求带有验证信息,这部分将会在下面详细解释
  • Access-Control-Expose-Headers: 允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息(貌似webkit没有实现这个)
  • Access-Control-Max-Age: 缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数
  • Access-Control-Allow-Methods: 允许使用的请求方法,以逗号隔开
  • Access-Control-Allow-Headers: 允许自定义的头部,以逗号隔开,大小写不敏感

然后浏览器通过返回结果的这些控制字段来决定是将结果开放给客户端脚本读取还是屏蔽掉。如果服务器没有配置cors,返回结果没有控制字段,浏览器会屏蔽脚本对返回信息的读取。

withCredentials

withCredentials是什么?

withCredentials是XMLHttpRequest的一个属性,表示跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)

实际中用途就是跨域请求是要不要携带cookie

在需要跨域携带cookie时,要把withCredentials设置为true,比如

var xhr = new XMLHttpRequest()
xhr.withCredentials = true
xhr.open('GET', 'http://localhost:8888/', true)
xhr.send(null)

服务端的设置

只有客户端设置当然不够了,服务端还需要设置两点

比如你页面所在的域名为http://www.abc.com,服务端的Access-Control-Allow-Origin,必须是http://www.abc.com

  1. Access-Control-Allow-Credentials

在响应头中,Access-Control-Allow-Credentials这个值也要设置为true,根据mdn上的说法,只有设置为true的时候,浏览器才会把响应结果暴露给你的js代码

  1. Access-Control-Allow-Origin

既然是跨域请求,服务端要设置Access-Control-Allow-Origin,告诉浏览器允许跨域,而且这个值必须指定域名,不能设置为*

尽管浏览器可以支持通配符,但是不能同时将凭证标志设置成true。

就像下面这种头部配置:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

这样配置浏览器将会报错,因为在响应具有凭据的请求时,服务器必须指定单个域,所不能使用通配符。简单的使用通配符将有效的禁用“Access-Control-Allow-Credentials”这个字段。这些限制和行为的结果就是许多CORS的实现方式是根据“Origin”这个头部字段的值来生成“AccessControl-Allow-Origin”的值

为什么不能两者共存?

默认情况下,如果没有设置“Access-Control-Allow-Credentials”这个头的话,浏览器发送的请求就不会带有用户的身份数据(cookie或者HTTP身份数据),所以就不会泄露用户隐私信息。下面这个图展示一个简单的CORS请求流:

ca4c461a9622a77f8e0bbf3c40bb6308.png

其实图片所展示的就是经典的CSRF攻击。而Origin的限制,是为了明确是哪个站点发送的请求,根据Origin就可以发现是钓鱼网站发起的请求。从而避免cookie的泄露。

参考文献:

CORS通信

跨域资源共享(CORS)安全性浅析

【web前端】withCredentials有什么作用

cors安全完全指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 图片识别 tess4j_图像文字识别(四):java调用tess4j识别图像文字

转自:https://blog.csdn.net/a745233700/article/details/80203340javajava调用tess4j识别图像文字Tesseract-OCR支持中文识别,而且开源和提供全套的训练工具,是快速低成本开发的首选。前面记录过在java中调用tesseract-orc,该方法…

sql in转换为join_同一个SQL语句,为啥性能差异咋就这么大呢?(1分钟系列)

《数据库允许空值,往往是悲剧的开始》一文通过explain来分析SQL的执行计划,来分析null对索引命中情况的影响,有不少朋友留言,问explain结果中的type字段,ref,ALL等不一样的值究竟是什么含义。今天花1分钟简…

java rmi接口 超时设置_Spring RMI客户端读超时设置 | 学步园

标准Java的RMI设置我所知道的有三种方式,其中第1、2种不区分框架均适用,但影响整个JVM级别的RMI服务1. 启动时设置sun.rmi.transport.tcp.responseTimeout,单位是毫秒java -Dsun.rmi.transport.tcp.responseTimeout502.在应用程序中设置环境变…

python黑客库长安十二时辰 更新_【Python成长之路】python 从零学爬虫 -- 没时间看《长安十二时辰》电视剧怎么办?直接爬取所有剧情吧!...

【写在前面】最近大火的《长安十二时辰》真的是好看,算的是良心网剧了。但是由于平时工作时间较长,经常无法准时追剧,并且又因为不想见到元裁那对挨千刀的(作为演员,演技是值得肯定的,角色演绎的让人看的心烦)。因此就…

java字符串笔试题_五道Java常见笔试题及答案汇总

1、String和StringBuffer的区别?答:Java平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行…

遥感原理与应用孙家炳_2.2遥感应用模型

章节概览遥感应用模型是遥感的一种定量化手段,通常在遥感领域有一个更广为人知的名词——定量遥感。但是定量遥感是一种方法模型而非技术手段,随着科学的发展,热门越来越体会到定量遥感的必要性。定量遥感的应用是十分广泛的,也是…

python升级命令debian_debian python 2.7.11 升级

首先下载源tar包可利用linux自带下载工具wget下载,如下所示:下载完成后到下载目录下,解压tar -zxvf Python-2.7.11.tgz进入解压缩后的文件夹cdPython-2.7.11在编译前先在/wp-content/local建一个文件夹python27(作为python的安装路径&#xf…

mysql必学十大必会_MYSQL 学习(一)--启蒙篇《MYSQL必知必会》

MYSQL必知必会一. DDL 数据定义语言Data Definition Language 是指CREATE,ALTER和DROP语句。DDL允许添加/修改/删除包含数据的逻辑结构,或允许用户访问/维护数据(数据库,表,键,视图......)的逻辑结构。DDL是关于“元数…

python连接wifi_python 自动重连wifi windows的方法

如下所示:# codingutf-8import urllib2import urllibfrom cookielib import CookieJarimport osimport reimport timeclass ConnectWeb(object):def __init__(self):self.cookiejarinmemory CookieJar()self.opener urllib2.build_opener(urllib2.HTTPCookieProce…

java for新循环_Java 8 新语法习惯 (for 循环的函数替代方案)

我们看这样一个示例public class ForDemo {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("Get set...");for (int i 0; i < 4; i) {System.out.println(i"...");}}}测试结果Get set...0...1...2...…

喜马拉雅 xm文件转m4a_喜马拉雅电台、课程语音如何转成文字?

今天看了一篇文章“AI面前人类一败涂地”就是说了AI的发展让所有的事情几乎都可以实现科技化&#xff0c;无需人工操作&#xff0c;工作效率还比人工要高很多。这样说来的确是这样。语音转换也是其中一门技术&#xff0c;人们现在对于语音的交流很多&#xff0c;比如社交软件的…

java url特殊字符转义字符_URL中包含有特殊字符,进行转义

String temp URLEncoder.encode(json);URL中的特殊字符有些符号在URL中是不能直接传递的&#xff0c;如果要在URL中传递这些特殊符号&#xff0c;那么就要使用他们的编码了。编码的格式为&#xff1a;%加字符的ASCII码&#xff0c;即一个百分号%&#xff0c;后面跟对应字符的A…

java 多重注解_Java注解-元数据、注解分类、内置注解和自定义注解

大家好&#xff0c;我是乐字节的小乐&#xff0c;上次说过了Java多态的6大特性|乐字节&#xff0c;接下来我们来看看Java编程里的注解。Java注解有以下几个知识点&#xff1a;元数据注解的分类内置注解自定义注解注解处理器Servlet3.0本文先介绍前面4个知识点&#xff1a;元数据…

python getattr函数_Python中的getattr()函数详解

在计算机编程中&#xff0c;自省是指这种能力&#xff1a;检查某些事物以确定它是什么、它知道什么以及它能做什么。自省向程序员提供了极大的灵活性和控制力。自省(introspection)&#xff0c;在计算机编程领域里&#xff0c;是指在运行时来判断一个对象的类型的能力。它是Pyt…

ie8不兼容java项目_常见IE8兼容性问题及解决

1、css3媒体查询IE8不支持媒体查询解决&#xff1a;respond.js&#xff0c;在页面中所有css文件的引用位置之后引用Respond.js2、HTML5新标签IE8不支持H5新标签解决&#xff1a;html5shiv.js&#xff0c;在页面中引用html5shiv.js文件。必须添加在页面的元素内&#xff0c;因为…

python对图像二值化_python如何二值化图像

在python中二值化图像的方法&#xff1a;首先将图片转化为灰色图像&#xff1b;然后自定义灰度界限&#xff1b;最后输入“photoImg.point(table,1)”命令(table为自己创建的数组名)即可二值化图像。# 图片二值化代码如下&#xff1a;from PIL import Imageimg Image.open(tes…

Java快速提升_java快速复习 一 基础语法

最近看很多算法书&#xff0c;比较不错的有不少都是java语言描述&#xff0c;所以用一天时间快速研究并整理java &#xff0c;参考资料&#xff1a;java入门经典Call this file "Example2.java".class Example2 {public static void main(String args[]) {int a&…

酷狗音乐linux版_酷狗音乐概念版APP内测获用户好评:极简化,更高级

这两天在网上冲浪的时候&#xff0c;发现不少网友都在安利一个叫做“酷狗音乐概念版”的APP&#xff0c;难道是酷狗又在闷声搞大事了&#xff1f;搜了一下发现&#xff0c;原来是酷狗音乐概念版APP已经开始进入内测阶段&#xff0c;尝试着下载使用&#xff0c;果然发现“更酷更…

java 计算器类图_多态计算器(封装、继承、多态、简单工厂)

一.封装向对象程序设计中&#xff0c;一个非常重要的技术便是封装&#xff0c;也就是把客观事物封装成抽象的类&#xff0c;并且类可以把自己的数据和方法只让可信的类或者对象操作&#xff0c;对不可信的进行信息隐藏。这样做的好处在于可以使类内部的具体实现透明化&#xff…

图书管理系统 java 源码_[源码和文档分享]基于C语言和SQL SERVER数据库实现的图书管理系统...

摘 要本文根据《数据库应用系统设计》课程要求而做。选择图书馆管理系统设计与开发是因为觉得图书馆管理系统对我们的帮助很大&#xff0c;并且经常去图书馆&#xff0c;对图书馆的大部分功能及流程还是比较了解&#xff0c;而且现在有些地方可能还不够完善。这次课程设计目标是…