摘要:瀏覽器的同源策略瀏覽器所遵守的同源策略是指限制不同源之間執(zhí)行特定操作。這正是同源策略想要規(guī)避的安全隱患。目前為止,你已經(jīng)充分了解同源策略這個主題。
我們之前提到過,AJAX技術(shù)使開發(fā)者能夠?qū)W⒂诨ヂ?lián)網(wǎng)中數(shù)據(jù)的傳輸,而不再拘泥于數(shù)據(jù)傳輸?shù)?strong>載體。通過AJAX技術(shù),我們獲取數(shù)據(jù)的方式變得更加靈活,可控和優(yōu)雅。
但是AJAX技術(shù)并不是一把萬能鑰匙,互聯(lián)網(wǎng)中的數(shù)據(jù)隱私和數(shù)據(jù)安全(例如你的銀行賬號和密碼)也非常重要,為了保護(hù)某些用戶數(shù)據(jù)的隱私與安全,瀏覽器使用“同源策略”限制了AJAX技術(shù)獲取數(shù)據(jù)的范圍和能力。但在一些合理的場景中,我們又不得不想辦法繞過同源策略,實現(xiàn)跨域請求資源。因此“跨域技術(shù)”一直成為開發(fā)者們經(jīng)久不衰的討論話題。
在“跨域獲取資源”這一主題中,我們將圍繞“同源策略”和“跨域”兩大主題展開,不但講述它們是什么,更說明了為什么要這么做。相信你在讀完該主題下的兩篇文章后,一定會對這兩大主題有一個清晰,系統(tǒng)的認(rèn)識。
需要提前聲明的是,本主題下的文章并不會像眾多相同主題的文章一樣羅列出所有的跨域技術(shù),而只會撿最主流的四種進(jìn)行講解。因為我并不打算寫“教你如何跨域”這樣類型的文章。
讓我們開始吧。
同源策略整個互聯(lián)網(wǎng)世界的數(shù)據(jù)要么存儲在服務(wù)端(即服務(wù)器,如數(shù)據(jù)庫,硬盤等)中,要么存儲在客戶端(即瀏覽器,如cookie,LocalStorage,sessionStorage)中?;ヂ?lián)網(wǎng)數(shù)據(jù)的傳輸實際上就是客戶端與服務(wù)端之間的交互。
而所謂的數(shù)據(jù)隱私與安全保護(hù),說白了就是數(shù)據(jù)擁有者對數(shù)據(jù)索取者發(fā)出警告:“不是你的你別動”。
搞清了這個原則,我們就很容易明白,如果你在客戶端,并且想要獲取服務(wù)端數(shù)據(jù),你首先需要通過服務(wù)器端的驗證,證明你有權(quán)限獲取數(shù)據(jù)(例如“登錄”),而如果你在服務(wù)端,想要獲取客戶端的某些數(shù)據(jù),你同樣需要客戶端通過某些方式驗證你有資格獲取相應(yīng)的數(shù)據(jù)資源。
那么上面提到的“某些方式”是什么呢?其中最重要的就是我們今天的主題之一 -- 瀏覽器的“同源策略”。
瀏覽器的“同源策略”瀏覽器所遵守的“同源策略”是指:限制不同源之間執(zhí)行特定操作。這涉及到兩個問題:什么是“源”?,以及“特定操作”是指什么?
讓我們停下來解釋一下這個概念:
一個源由協(xié)議,域名和端口三部分組成,這三者任一一個不同都會被瀏覽器識別為不同的源;
上文所提到的特定操作是指:
讀取 Cookie,LocalStorage 和 IndexDB;
獲取 DOM 元素;
發(fā)送 AJAX 請求;
在搞清了同源策略的概念之后,讓我們看看瀏覽器是出于怎樣的考慮,一直堅守著同源策略:
為什么要有“源”的概念?因為不同的源,大多數(shù)情況下就意味著它們在互聯(lián)網(wǎng)中歸屬于不同的站點(或是被用作不同的用途)。也就是說它們是不同的項目,有不同的文件根目錄,那么它們的數(shù)據(jù)也不應(yīng)該共享也就理所應(yīng)當(dāng)了,否則數(shù)據(jù)的隱私和安全也無從談起。不過請注意,我上面所說的話是基于“不同源就彼此不相干”的假設(shè),這其實存在一些問題,我們之后會提到。
為什么不能執(zhí)行“特定操作”?這個需要我們假設(shè),如果我們想做一些“壞事”,并且瀏覽器允許我們執(zhí)行這些“特定操作”,我們作為“壞人”能做什么:
首先,由于很多網(wǎng)站使用瀏覽器存儲用戶的用戶名和密碼,那么我們便可以在A域中(我們在服務(wù)器上托管的網(wǎng)站)讀取任意來訪用戶的所有Cookie信息(沒有同源策略的保護(hù),該用戶所有網(wǎng)站的Cookie記錄都是透明的),我們就可以利用這些Cookie信息偽裝成來訪用戶做任何事,而在現(xiàn)實世界,出于同源政策的保護(hù),我們只能訪問用戶該域下的Cookie信息,也就是說,我們只能訪問我們自己設(shè)置的Cookie信息。
其次,如果我們能夠獲取不同域下的DOM元素,我們就可以通過標(biāo)簽在我們的A域網(wǎng)站上引入B域網(wǎng)站,然后誘使用戶在B域網(wǎng)站操作,由于我們能夠跨域獲取DOM元素,因此我們可以操作B域網(wǎng)站的DOM結(jié)構(gòu),用戶輸入的一切信息,以及用戶操作的DOM元素就都在我們的掌控之中了。這正是同源策略想要規(guī)避的安全隱患。
最后,為什么要禁止不同源的站點發(fā)送AJAX請求呢?這個說起來有些復(fù)雜,我們首先要對Cookie的運作原理有一個大致的了解:
當(dāng)我們設(shè)置Cookie時,除了存放鍵值對形式的數(shù)據(jù)信息外,瀏覽器還會為Cookie的一些屬性填充默認(rèn)值(我們也可以手動修改這些屬性的值)。在這些屬性中,我們需要關(guān)注domain和path兩個屬性,它們一個代表域名,一個代表路徑,兩者加起來構(gòu)成了一個確定這條Cookie何時被調(diào)用和訪問的URL。與此同時,瀏覽器自己維護(hù)的Cookie文件中也會添加這一條新創(chuàng)建的Cookie數(shù)據(jù)。
當(dāng)我們在瀏覽器中發(fā)送HTTP請求時,瀏覽器首先會檢查請求地址并在自己所維護(hù)的Cookie文件中尋找匹配的Cookie信息,將其添加到請求頭中的Cookie屬性內(nèi),然后向服務(wù)器發(fā)送請求。請注意,這個自動添加相應(yīng)Cookie信息的過程是瀏覽器自己偷偷幫我們做到的,也就是說,我們自己無法控制這個過程。
下面重點來了,當(dāng)我們的HTTP請求到達(dá)服務(wù)器時,服務(wù)器返回的響應(yīng)中,響應(yīng)頭會原封不動的返回我們發(fā)送給他的Cookie信息。嗅到危險的味道了嗎?我們雖然不能在發(fā)送請求前獲得Cookie信息,但是在發(fā)送請求后,我們還是能夠獲得用戶的Cookie!
讓我再進(jìn)一步解釋一下這和AJAX有什么關(guān)系,假設(shè)我們在自己的服務(wù)器上托管了站點A,并在其中隱藏了一段腳本,每個登錄站點A的人都會自動發(fā)送AJAX請求至站點B(提示:站點B是一個銀行),那么在沒有瀏覽器同源策略的情況下,如果站點A中的訪問者恰好有Cookie中保留站點B信息的用戶,通過AJAX請求返回的響應(yīng)頭,我們一樣可以拿到這位用戶的站點B Cookie,從而偽裝成用戶在站點B登錄,做一些違法亂紀(jì)的事情(CSRF攻擊即是利用了這個原理,只不過出于同源策略限制,并不能通過發(fā)起AJAX的方式)。
雖然有些費勁,但是現(xiàn)在你應(yīng)該明白為什么同源策略要阻止跨域發(fā)送AJAX了吧?(我終于將這個概念說清楚了,真是費了不少力氣 ?)
想要了解更多關(guān)于Cookie的信息,可以參考這篇文章
同源策略的表現(xiàn)看看我們的任務(wù)清單,我們解釋了什么是同源策略以及瀏覽器為什么要有同源策略,但至今為止,我們還不曾看到,在瀏覽器同源策略的限制下,當(dāng)我們想要獲取跨域Cookie,DOM結(jié)構(gòu)和發(fā)送AJAX時,我們是如何被“拒絕”的。
首先,我們在一個域下只能讀取該域下的Cookie值。當(dāng)我們在頁面中使用標(biāo)簽時,我們獲取對應(yīng)DOM節(jié)點下只有一個空空的#document節(jié)點,并沒有額外的DOM信息。
而對于AJAX,瀏覽器其實并沒有阻止我們向不同域發(fā)送請求,其阻止的是這次請求的響應(yīng),也就是說服務(wù)端其實接收到了這次請求,只是響應(yīng)被瀏覽器解析時被瀏覽器發(fā)現(xiàn)違背了同源策略而被拒絕,此時,瀏覽器會在控制臺中打印出一條錯誤信息。
另外需要注意的是,對于XHR請求,實際上我們在請求報頭也不會看到相應(yīng)的Cookie信息,這是因為CORS標(biāo)準(zhǔn)中做了規(guī)定,默認(rèn)情況下,瀏覽器在發(fā)送跨域請求時,不能發(fā)送任何認(rèn)證信息,比如cookies和HTTP authentication schemes。除非你顯式的將xhr實例的withCredentials屬性的值設(shè)置為true并且服務(wù)器端也允許客戶端請求攜帶認(rèn)證信息(即服務(wù)器端在響應(yīng)頭中設(shè)置了Access-Control-Allow-Credentials: true)。
要在跨域請求頭中顯示Cookie真是不容易對吧?
但是,等等!CORS標(biāo)準(zhǔn)是什么?
問得好,在下一篇以“跨域發(fā)送請求”為主題的文章中,我們會詳細(xì)談到他。目前為止,你已經(jīng)充分了解“同源策略”這個主題。Good Job!
現(xiàn)在讓我們先暫時休息一下,下一篇見 ?。
? Hey!喜歡這篇文章嗎?別忘了在下方? 點贊讓我知道。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90156.html
摘要:一基于維基百科的定義,是一種在單個連接上進(jìn)行全雙工通訊的協(xié)議。讓我們看看這個模型的具體實現(xiàn)下面是客戶端告知服務(wù)端要升級為協(xié)議的報頭下面是服務(wù)端向客戶端返回的響應(yīng)報頭想知道這些報頭中的字段中代表什么可以參考維基百科下的說明。 讓我們先簡單回顧一下之前談到的內(nèi)容,AJAX是一種無頁面刷新的獲取服務(wù)器資源的混合技術(shù)。而基于瀏覽器的同源策略,不同域之間不可以發(fā)送AJAX請求。但是在某些情境下,...
摘要:瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用跨域請求資源時,同源策略又會成為開發(fā)者的阻礙。我們之前提到過,如果想要繞過瀏覽器同源策略,實現(xiàn)使用技術(shù)跨域獲取資源,需要服務(wù)端和客戶端的協(xié)同合作。 瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用AJAX跨域請求資源時,同源策略又會成為開發(fā)者的阻礙。在本文中,我們會簡單介紹需...
摘要:需要注意的是,并不是的替代品,兩者各自有其適應(yīng)的場景。但為了方便交流,我們通常將獲取資源的一方稱為客戶端主要的工具是瀏覽器,而將派發(fā)資源的一方稱為服務(wù)端又稱為服務(wù)器。它可以幫助我們?yōu)橹蟾拍罴?xì)節(jié)的學(xué)習(xí)打下良好基礎(chǔ)。 再也不學(xué)AJAX了是一個與AJAX主題相關(guān)的文章系列,包含以下三個部分的內(nèi)容: AJAX概述:主要回答AJAX是什么這個問題; 使用AJAX:介紹如何通過JavaSc...
摘要:同源策略做了很嚴(yán)格的限制,但是在實際的場景中,又確實有很多地方需要突破同源策略的限制,也就是我們常說的跨域。使用跨域由于同源策略,一般來說位于的網(wǎng)頁無法與不是的服務(wù)器溝通,而的元素是一個例外。 本菜雞最近在寫某個頁面請求數(shù)據(jù)時,報了如下的錯誤。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...
摘要:同源策略做了很嚴(yán)格的限制,但是在實際的場景中,又確實有很多地方需要突破同源策略的限制,也就是我們常說的跨域。使用跨域由于同源策略,一般來說位于的網(wǎng)頁無法與不是的服務(wù)器溝通,而的元素是一個例外。 本菜雞最近在寫某個頁面請求數(shù)據(jù)時,報了如下的錯誤。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...
閱讀 1166·2023-04-25 17:28
閱讀 3617·2021-10-14 09:43
閱讀 3978·2021-10-09 10:02
閱讀 1951·2019-08-30 14:04
閱讀 3142·2019-08-30 13:09
閱讀 3280·2019-08-30 12:53
閱讀 2907·2019-08-29 17:11
閱讀 1833·2019-08-29 16:58