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.pswp.cn/news/528976.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/528976.shtml
英文地址,請注明出處:http://en.pswp.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;而且現在有些地方可能還不夠完善。這次課程設計目標是…