點選關註公眾號,Java幹貨 及時送達 👇
前言
最近博主在字節面試中遇到這樣一個面試題,這個問題也是前端面試的高頻問題,因為在前端開發的日常開發中我們總是會與post請求打交道,一個小小的post請求也是牽扯到很多知識點的,博主在這給大家細細道來。
同源策略
在瀏覽器中,內容是很開放的,任何資源都可以接入其中,如 JavaScript 檔、圖片、音訊、視訊等資源,甚至可以下載其他站點的可執行檔。
但也不是說瀏覽器就是完全自由的,如果不加以控制,就會出現一些不可控的局面,例如會出現一些安全問題,如:
跨站指令碼攻擊(XSS)
SQL 隱碼攻擊
OS 命令隱碼攻擊
HTTP 首部隱碼攻擊
跨站點請求偽造(CSRF)
等等…
如果這些都沒有限制的話,對於我們使用者而言,是相對危險的,因此需要一些安全策略來保障我們的私密和數據安全。
這就引出了最基礎、最核心的安全策略:同源策略。
什麽是同源策略
同源策略是一個重要的安全策略,它用於限制一個源的文件或者它載入的指令碼如何能與另一個源的資源進行互動。
如果兩個 URL 的協定、主機和埠都相同,我們就稱這兩個 URL 同源。
協定:協定是定義了數據如何在電腦內和之間進行交換的規則的系統,例如 HTTP、HTTPS。
主機:是已連線到一個電腦網路的一台電子電腦或其他裝置。網路主機可以向網路上的使用者或其他節點提供資訊資源、服務和套用。使用 TCP/IP 協定族參與網路的電腦也可稱為 IP 主機。
埠:主機是電腦到電腦之間的通訊,那麽埠就是行程到行程之間的通訊。
如下表給出了與 URL http://test.home.com:8080/dir/page.html 的源進行對比的範例:
同源策略主要表現在以下三個方面:DOM、Web 數據和網路。
DOM 存取限制:同源策略限制了網頁尾本(如 JavaScript)存取其他源的 DOM。這意味著透過指令碼無法直接存取跨源頁面的 DOM 元素、內容或方法。這是為了防止惡意網站從其他網站竊取敏感資訊。
Web 數據限制:同源策略也限制了從其他源載入的 Web 數據(例如 XMLHttpRequest 或 Fetch API)。在同源策略下,XMLHttpRequest 或 Fetch 請求只能發送到與當前網頁具有相同源的目標。這有助於防止跨站點請求偽造(CSRF)等攻擊。
網路通訊限制:同源策略還限制了跨源的網路通訊。瀏覽器會阻止從一個源發出的請求獲取來自其他源的響應。這樣做是為了確保只有受信任的源能夠與伺服器進行通訊,以避免惡意行為。
出於安全原因,瀏覽器限制從指令碼內發起的跨源 HTTP 請求,XMLHttpRequest 和 Fetch API,只能從載入應用程式的同一個域請求 HTTP 資源,除非使用 CORS 表頭檔
CORS
對於瀏覽器限制這個詞,要著重解釋一下:不一定是瀏覽器限制了發起跨站請求,也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。
瀏覽器將不同域的內容隔離在不同的行程中,網路行程負責下載資源並將其送到渲染行程中,但由於跨域限制,某些資源可能被阻止載入到渲染行程。如果瀏覽器發現一個跨域響應包含了敏感數據,它可能會阻止指令碼存取這些數據,即使網路行程已經獲得了這些數據。CORB 的目標是在渲染之前盡早阻止惡意程式碼獲取跨域數據。
CORB 是一種安全機制,用於防止跨域請求惡意存取跨域響應的數據。渲染行程會在 CORB 機制的約束下,選擇性地將哪些資源送入渲染行程供頁面使用。
例如,一個網頁可能透過 AJAX 請求從另一個域的伺服器獲取數據。雖然某些情況下這樣的請求可能會成功,但如果瀏覽器檢測到請求返回的數據可能包含惡意程式碼或與同源策略沖突,瀏覽器可能會阻止網頁存取返回的數據,以確保使用者的安全。
跨源資源共享(Cross-Origin Resource Sharing,CORS)是一種機制,允許在受控的條件下,不同源的網頁能夠請求和共享資源。由於瀏覽器的同源策略限制了跨域請求,CORS 提供了一種方式來解決在 Web 套用中進行跨域數據交換的問題。
CORS 的基本思想是,伺服器在響應中提供一個檔頭(HTTP 頭),指示哪些源被允許存取資源。瀏覽器在發起跨域請求時會先發送一個預檢請求(OPTIONS 請求)到伺服器,伺服器透過設定適當的 CORS 檔頭來指定是否允許跨域請求,並指定允許的請求源、方法、檔頭等資訊。
簡單請求
不會觸發 CORS 預檢請求。這樣的請求為 簡單請求,。若請求滿足所有下述條件,則該請求可視為 簡單請求:
HTTP 方法限制:只能使用 GET、HEAD、POST 這三種 HTTP 方法之一。如果請求使用了其他 HTTP 方法,就不再被視為簡單請求。
自訂檔頭限制:請求的 HTTP 檔頭只能是以下幾種常見的檔頭:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(僅限於 application/x-www-form-urlencoded、multipart/form-data、text/plain)。HTML 頭部 header field 欄位:DPR、Download、Save-Data、Viewport-Width、WIdth。如果請求使用了其他檔頭,同樣不再被視為簡單請求。
請求中沒有使用 ReadableStream 物件。
不使用自訂請求檔頭:請求不能包含使用者自訂的檔頭。
請求中的任意 XMLHttpRequestUpload 物件均沒有註冊任何事件監聽器;XMLHttpRequestUpload 物件可以使用 XMLHttpRequest.upload 內容存取
預檢請求
非簡單請求的 CORS 請求,會在正式通訊之前,增加一次 HTTP 查詢請求,稱為 預檢請求。
需預檢的請求要求必須首先使用 OPTIONS 方法發起一個預檢請求到伺服器,以獲知伺服器是否允許該實際請求。預檢請求 的使用,可以避免跨域請求對伺服器的使用者數據產生未預期的影響。
例如我在自己的網站上刪除一條記錄:
它首先會發起一個預檢請求,預檢請求的頭資訊包括兩個特殊欄位:
Access-Control-Request-Method:該欄位是必須的,用來列出瀏覽器的 CORS 請求會用到哪些 HTTP 方法,上例是 POST。
Access-Control-Request-Headers:該欄位是一個逗號分隔的字串,指定瀏覽器 CORS 請求會額外發送的頭資訊欄位,上例是 content-type,x-secsdk-csrf-token。
access-control-allow-origin:在上述例子中,表示 https://xxx.cn 可以請求數據,也可以設定為* 符號,表示統一任意跨源請求。
access-control-max-age:該欄位可選,用來指定本次預檢請求的有效期,單位為秒。上面結果中,有效期是 1 天(86408 秒),即允許緩存該條回應 1 天(86408 秒),在此期間,不用發出另一條預檢請求。
一旦伺服器透過了 預檢請求,以後每次瀏覽器正常的 CORS 請求,就都跟簡單請求一樣,會有一個 Origin 頭資訊欄位。伺服器的回應,也都會有一個 Access-Control-Allow-Origin 頭資訊欄位。
上面頭資訊中,Access-Control-Allow-Origin 欄位是每次回應都必定包含的。
附帶身份憑證的請求與通配符
在響應附帶身份憑證的請求時:
為了避免惡意網站濫用 Access-Control-Allow-Origin 頭部欄位來獲取使用者敏感資訊,伺服器在設定時不能將其值設為通配符 *。相反,應該將其設定為特定的域,例如:Access-Control-Allow-Origin: https://xxx.cn。透過將 Access-Control-Allow-Origin 設定為特定的域,伺服器只允許來自指定域的請求進行跨域存取。這樣可以限制跨域請求的範圍,避免不可信的域獲取到使用者敏感資訊。
為了避免潛在的安全風險,伺服器不能將 Access-Control-Allow-Headers 的值設為通配符 *。這是因為不受限制的請求頭可能被濫用。相反,應該將其設定為一個包含檔頭名稱的列表,例如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type。透過將 Access-Control-Allow-Headers 設定為明確的檔頭名稱列表,伺服器可以限制哪些自訂請求頭是允許的。只有在允許的檔頭列表中的頭部欄位才能在跨域請求中被接受。
為了避免潛在的安全風險,伺服器不能將 Access-Control-Allow-Methods 的值設為通配符 *。這樣做將允許來自任意域的請求使用任意的 HTTP 方法,可能導致濫用行為的發生。相反,應該將其設定為一個特定的請求方法名稱列表,例如:Access-Control-Allow-Methods: POST, GET。透過將 Access-Control-Allow-Methods 設定為明確的請求方法列表,伺服器可以限制哪些方法是允許的。只有在允許的方法列表中的方法才能在跨域請求中被接受和處理。
對於附帶身份憑證的請求(通常是 Cookie)
這是因為請求的檔頭中攜帶了 Cookie 資訊,如果 Access-Control-Allow-Origin 的值為 *,請求將會失敗。而將 Access-Control-Allow-Origin 的值設定為 https://xxx.cn,則請求將成功執行。
另外,響應檔頭中也攜帶了 Set-Cookie 欄位,嘗試對 Cookie 進行修改。如果操作失敗,將會丟擲異常。
完整的請求流程圖
總結
預檢請求是在進行跨域資源共享 CORS 時,由瀏覽器自動發起的一種 OPTIONS 請求。它的存在是為了保障安全,並允許伺服器決定是否允許跨域請求。
跨域請求是指在瀏覽器中向不同網域名稱、不同埠或不同協定的資源發送請求。出於安全原因,瀏覽器預設禁止跨域請求,只允許同源策略。而當網頁需要進行跨域請求時,瀏覽器會自動發送一個預檢請求,以確定是否伺服器允許實際的跨域請求。
預檢請求中包含了一些額外的頭部資訊,如 Origin 和 Access-Control-Request-Method 等,用於告知伺服器實際請求的方法和來源。伺服器收到預檢請求後,可以根據這些頭部資訊,進行驗證和授權判斷。如果伺服器認可該跨域請求,將返回一個包含 Access-Control-Allow-Origin 等頭部資訊的響應,瀏覽器才會繼續發送實際的跨域請求。
使用預檢請求機制可以有效地防範跨域請求帶來的安全風險,保護使用者數據和私密。
來源:blog.csdn.net/A_D_H_E_R_E/article/details/132483843
END
看完本文有收獲?請轉發分享給更多人
關註「Java編程鴨」,提升Java技能
關註Java編程鴨微信公眾號,後台回復:碼農大禮包可以獲取最新整理的技術資料一份。涵蓋Java 框架學習、架構師學習等!
文章有幫助的話,在看,轉發吧。
謝謝支持喲 (*^__^*)