自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

CORS為什么能保障安全?為什么只對復(fù)雜請求做預(yù)檢?

開發(fā) 前端 安全
這篇文章會圍繞CORS是如何保障安全的的,講清這幾個問題。讀完可以對CORS知其然,并知其所以然。

大家好,我是年年!提起CORS,大部分的文章都在寫什么是簡單請求、什么是復(fù)雜請求,復(fù)雜請求預(yù)檢的流程又是怎樣。

但如果問你:

  1. CORS為什么要帶上源,這是為了保障當(dāng)前站點的安全還是目的服務(wù)器的安全?
  2. 為什么區(qū)分簡單請求和復(fù)雜請求,只對復(fù)雜請求做預(yù)檢?

這篇文章會圍繞CORS是如何保障安全的的,講清這幾個問題。讀完可以對CORS知其然,并知其所以然。

什么是CORS

相信每個前端的控制臺都中都被打印過這樣一段話,告訴你:你的跨域請求策略攔截啦!

首先要明確的一點,CORS的目的不是攔截請求,反倒是為了讓其能正常請求。

CORS誕生的背景是「同源策略」。這是一個相當(dāng)嚴(yán)苛的規(guī)定,它禁止了跨域的AJAX請求。但實際的開發(fā)中又有這樣的需求,于是開一個口子——只要配置了CORS的對應(yīng)規(guī)則,跨域請求就能正常進(jìn)行。這也正和CORS的名字對應(yīng)起來了——「跨域資源共享」,就是為了能讓跨域請求在「同源策略」的大背景下進(jìn)行。

回到上面提到控制臺報錯,這不是阻止你做跨域請求,而是提示你:因為沒有按照CORS要求做配置,不得不暫時攔截。

怎樣配置CORS

上文講清了,只要按照CORS要求做配置,就能突破同源策略的限制,下面將會講述如何配置。

這部分不需要前端操心,完全后端來做:在響應(yīng)頭里面加一個字段Access-Control-Allow-Origin(允許請求的來源),這個值要把前端的源包含進(jìn)去。

舉個例子:請求的后端接口是http://fe_nian,你本地正在開發(fā)前端工程跑在8080端口。那么后端會在響應(yīng)頭里加上Access-Control-Allow-Origin:*來允許http://localhost:8080這個源去做跨域請求,因為*是所有的意思。

跨域請求的流程

CORS把請求分成簡單請求和復(fù)雜請求,劃分的依據(jù)是“是否會產(chǎn)生副作用”。

簡單貼一下定義,同時滿足下面這兩個條件的是簡單請求

  1. 請求方法是HEAD/GET/POST。
  2. 請求體的文件類型只能是form-urlencoded、form-data、text/plain(這類文章很多,不再贅述,可以看阮一峰-跨域資源共享)。

對于簡單請求,流程如下:

  1. 瀏覽器發(fā)起請求,并且自動加上請求的來源origin給服務(wù)器檢查。
  2. 服務(wù)器返回數(shù)據(jù),并返回檢查結(jié)果,配置CORS響應(yīng)頭。
  3. 瀏覽器檢查CORS響應(yīng)頭,如果包含了當(dāng)前的源則放行,反之?dāng)r截。

這里需要注意,瀏覽器是攔截響應(yīng),而不是攔截請求,跨域請求是發(fā)出去的,并且服務(wù)端做了響應(yīng),只是瀏覽器攔截了下來。

對于復(fù)雜請求,整個流程如下:

  1. 瀏覽器發(fā)起預(yù)檢請求,帶上請求的來源origin,不包含請求體。
  2. 服務(wù)器返回檢查結(jié)果,配置CORS頭。
  3. 瀏覽器發(fā)起真正請求。
  4. 瀏覽器返回數(shù)據(jù)。

瀏覽器會檢查第2步中拿到的CORS頭,如果沒有包含當(dāng)前的源,后續(xù)的第3、4步都不會進(jìn)行,也就是不會發(fā)起真正請求。

為什么要帶上源

CORS給開發(fā)帶來了便利,同時也帶來了安全隱患——CSRF攻擊。

它的基本流程如下:

  1. 用戶登錄受害網(wǎng)站,把獲取的身份憑證保存在瀏覽器的cookie中。也就是上圖流程的①②③。
  2. 用戶用同一瀏覽器打開黑客網(wǎng)站,黑客網(wǎng)站向受害網(wǎng)站服務(wù)器發(fā)起一個惡意請求,這時瀏覽器會自動從cookie中取出身份憑證,把它帶上。也就是上圖的④⑤。
  3. 受害網(wǎng)站服務(wù)端發(fā)現(xiàn)有身份憑證,惡意請求被成功受理。

如果嚴(yán)格按照同源政策,第2步的跨域請求不能進(jìn)行的,也就不會造成危害。所以CORS策略的心智模型是:所有跨域請求都是不安全的,瀏覽器要帶上來源給服務(wù)器檢驗。

如果做過服務(wù)端開發(fā),應(yīng)該知道,服務(wù)端不存在跨域一說,去獲取另一個服務(wù)器的資源是再順暢不過的事情。因為服務(wù)端不像瀏覽器一樣,作為“容器”存貯著用戶身份憑證——也就是上面的第1步發(fā)生的事情,它去做跨域請求沒有這樣的風(fēng)險。

為什么只對復(fù)雜請求做預(yù)檢

上文提到,劃分簡單請求和復(fù)雜請求的依據(jù)是“是否產(chǎn)生副作用”。這里的副作用指對數(shù)據(jù)庫做出修改:使用GET請求獲取新聞列表,數(shù)據(jù)庫中的記錄不會做出改變,而使用PUT請求去修改一條記錄,數(shù)據(jù)庫中的記錄就發(fā)生了改變。

對于簡單請求,瀏覽器只會在請求頭加上一個origin字段標(biāo)識請求來源;對于非簡單請求,瀏覽器會先發(fā)出一個預(yù)檢請求,獲得肯定回答后才會發(fā)送真正的請求,下面會講清楚為什么這么做。

可以假設(shè)網(wǎng)站被CSRF攻擊了——黑客網(wǎng)站向銀行的服務(wù)器發(fā)起跨域請求,并且這個銀行的安全意識很弱,只要有登錄憑證cookie就可以成功響應(yīng):

黑客網(wǎng)站發(fā)起一個GET請求,目的是查看受害用戶本月的賬單。銀行的服務(wù)器會返回正確的數(shù)據(jù),不過影響并不大,而且由于瀏覽器的攔截,最后黑客也沒有拿到這份數(shù)據(jù);

黑客網(wǎng)站發(fā)起一個PUT請求,目的是把受害用戶的賬戶余額清零。瀏覽器會首先做一次預(yù)檢,發(fā)現(xiàn)收到的響應(yīng)并沒有帶上CORS響應(yīng)頭,于是真正的PUT請求不會發(fā)出;

幸好有預(yù)檢機(jī)制,否則PUT請求一旦發(fā)出,黑客的攻擊就成功了。

結(jié)語

回到開頭的兩個問題,不難得出答案:

  1. 對于跨域請求帶上請求來源,是為了防止CSRF攻擊;瀏覽器的心智模型是:跨域請求都是不安全的,CORS的機(jī)制是為了保障請求目的服務(wù)器的安全。
  2. 依據(jù)是否對服務(wù)器有副作用,劃分了簡單請求和復(fù)雜請求(但由于歷史原因,表單POST請求也被劃分成了簡單請求),預(yù)檢機(jī)制會把不安全的復(fù)雜請求攔截下來,避免對服務(wù)器造成危害,而簡單請求通常不會對服務(wù)器的資源作出修改,即使發(fā)出危害不大。


責(zé)任編輯:姜華 來源: 前端私教年年
相關(guān)推薦

2021-03-29 16:32:03

軟件代碼程序員

2022-12-22 21:01:11

2022-03-30 08:21:57

合并HTTP

2021-04-21 07:31:01

ElasticSearMySQLCPU

2022-06-01 23:27:38

區(qū)塊鏈加密貨幣數(shù)字資產(chǎn)

2021-09-29 16:53:53

區(qū)塊鏈數(shù)據(jù)技術(shù)

2021-05-30 09:25:48

HttpETag 網(wǎng)絡(luò)協(xié)議

2020-08-10 09:07:00

數(shù)據(jù)庫IT技術(shù)

2021-06-30 06:56:18

數(shù)據(jù)泄露零信任網(wǎng)絡(luò)安全

2023-04-10 15:41:35

2024-01-19 08:42:45

Java線程字符串

2017-12-20 09:52:50

2022-06-09 16:48:10

TensorFlow機(jī)器學(xué)習(xí)

2017-11-29 12:06:07

2021-02-03 16:54:39

區(qū)塊鏈比特幣技術(shù)

2018-10-29 13:11:54

深度學(xué)習(xí)CNN提取圖像

2016-10-17 23:20:41

2018-04-24 15:53:52

2020-04-22 20:35:02

HashMap線程安全

2023-05-23 16:08:19

點贊
收藏

51CTO技術(shù)棧公眾號