1. HTTP 和 HTTPS
定義
超文字傳輸協議(HyperText Transfer Protocol,HTTP)是一種用於分散式、協作式和超媒體資訊系統的應用層協議。HTTP是全球資訊網的資料通訊的基礎。
HTTPS 是一種通過計算機網路進行安全通訊的傳輸協議,經由 HTTP 進行通訊,利用 SSL/TLS 建立全通道,加密資料包。HTTPS使用的主要目的是提供對網站伺服器的身份認證,同時保護交換資料的隱私與完整性。
區別
- HTTPS 協議需要到 CA 申請證照,一般免費證照很少,需要交費。
- HTTP 是超文字傳輸協議,資訊是明文傳輸,HTTPS 則是具有安全性的 SSL 加密傳輸協議。
- HTTP 和 HTTPS 使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。
- HTTP 的連線很簡單,是無狀態的;HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網路協議,比 HTTP 協議安全。
SSL 握手過程
- 客戶端給出協議的版本號、一個客戶端生成的隨機數和客戶端支援的加密演算法;
- 服務端在客戶端給出的加密演算法列表中選出一種,並給出數字證照和一個服務端生成的額隨機數;
- 客戶端確認數字證照的有效性,然後生成一個新的隨機數,並使用數字證照中的公鑰加密這個隨機數;
- 服務端使用私鑰解密,獲取客戶端發來的隨機數;
- 客戶端和服務端根據約定的加密方法,使用之前的三個隨機數,生成對話金鑰,這個金鑰會用來加密接下來的整個通訊過程
2. TCP 三次握手
3. TCP 和 UDP
- TCP 面向連線,UDP 是無連線的,即傳送資料之前不需要建立連線。
- TCP 提供可靠的服務。也就是說,通過TCP連線傳送的資料,無差錯,不丟失,不重複,且按序到達;UDP 盡最大努力交付,即不保證可靠交付。
- TCP 面向位元組流,實際上是 TCP 把資料看成一連串無結構的位元組流;UDP 是面向報文的。UDP 沒有擁塞控制,因此網路出現擁塞不會使源主機的傳送速率降低(對實時應用很有用,如 IP 電話,實時視訊會議等)。
- 每一條 TCP 連線只能是點到點的;UDP 支援一對一,一對多,多對一和多對多的互動通訊。
- TCP 首部開銷 20 位元組;UDP 的首部開銷小,只有 8 個位元組。
- TCP 的邏輯通訊通道是全雙工的可靠通道,UDP則是不可靠通道。
4. WebSocket
- WebSocket 是 HTML5 中的協議,支援持久連續,HTTP 協議不支援永續性連線。
- WebSocket 是基於 HTTP 協議的,或者說借用了 HTTP 協議來完成一部分握手,在握手階段 與 HTTP 是相同的。指定兩個屬性,
upgrade
和connection
。Upgrade: websocket Connection: Upgrade
5. HTTP1.0/HTTP1.1/HTTP2/HTTP3
HTTP1.0 和 HTTP1.1
- HTTP1.0 中主要使用 header 裡的
If-Modified-Since
,Expires
來做為快取判斷的標準,HTTP1.1 則引入了更多的快取控制策略例如Entity tag
,If-Unmodified-Since
,If-Match
,If-None-Match
等更多可供選擇的快取頭來控制快取策略。 - HTTP 1.1 支援長連線(PersistentConnection)和請求的流水線(Pipelining)處理,在一個 TCP 連線上可以傳送多個 HTTP 請求和響應,減少了建立和關閉連線的消耗和延遲,在 HTTP1.1 中預設開啟
Connection:keep-alive
,一定程度上彌補了 HTTP1.0 每次請求都要建立連線的缺點。
HTTP1 和 HTTP2.0
HTTP1 缺點
- TCP連線數限制 (可通過域名分片解決)
- 頭部阻塞
- 明文傳輸不安全
HTTP2
- 二進位制分幀,幀是資料傳輸的最小單位,以二進位制傳輸代替原本的明文傳輸,原本的報文訊息被劃分為更小的資料幀
- 首部壓縮
- 多路複用
- 服務端推送
HTTP3
QUIC協議(全稱Quick UDP Internet Connections,快速UDP網際網路連線)
- 實現了類似TCP的流量控制、傳輸可靠性的功能。
- 整合了TLS加密功能。
- 實現了HTTP/2中的多路複用功能。
6. HTTP 狀態碼
- 1xx:訊息,請求已被伺服器接收,繼續處理
- 2xx:成功,請求已成功被伺服器接收、理解、並接受
- 3xx:重定向,需要後續操作才能完成這一請求
- 301 永久移動
- 302 臨時移動
- 304 未修改,使用快取
- 4xx:請求錯誤,請求含有詞法錯誤或者無法被執行
- 401 需要認證
- 403 無許可權
- 404 未找到
- 405 方法不被允許
- 5xx:伺服器錯誤,伺服器在處理某個正確請求時發生錯誤
7. HTTP 常用請求頭
- Accept 可接受的相應內容型別
- Accept-Charset 可接受的字符集
- If-Modified-Since、If-None-Match 未修改返回304
- 還有很多……待補充 TODO
8. 強快取、協商快取
快取好處
(1)減少頁面載入時間;(2)減少伺服器負載;
強快取
瀏覽器在載入資源時,先判斷它是否命中強快取,強快取如果命中,瀏覽器直接從自己的快取中讀取資源,不會發請求到伺服器。
HTTP1.0 - Expires
請求資源時伺服器會返回 Expires
,(比如expires: Fri, 01 Jan 2021 00:00:00 GMT
)下次請求前用 Expires
跟當前的請求時間比較,如果請求時間在 Expires
指定的時間之前,就能命中快取,否則從伺服器載入資源。缺點是客戶端時間和伺服器時間有誤差。
HTTP1.1 - Cache-Control
伺服器返回 Cache-Control
,這是一個相對時間,表示快取有效期,單位秒。(比如:cache-control: max-age=1800, s-maxage=60
其中 s-maxage
一般應用於快取伺服器)。
協商快取
當瀏覽器對某個資源的請求沒有命中強快取,就會發一個請求到伺服器,驗證協商快取是否命中,如果協商快取命中,請求響應返回 304 Not Modified
。
Last-Modified,If-Modified-Since
伺服器返回資源會返回 Last-Modified
,表示這個資源在伺服器上的最後修改時間。(比如:last-modified: Tue, 18 Jan 2022 02:52:12 GMT
),下次請求客戶端就會加上請求頭 If-Modified-Since
,且對應值會伺服器返回的時間(if-modified-since: Tue, 18 Jan 2022 02:52:12 GMT
)。
伺服器再次收到資源請求時,根據瀏覽器傳過來 If-Modified-Since
和資源在伺服器上的最後修改時間判斷資源是否有變化,如果沒有變化則返回 304 Not Modified
,但是不會返回資源內容;如果有變化,就正常返回資源內容。
缺點是有時檔案改動但是時間沒有修改(間隔時間過短),或者時間修改但是並沒有改動檔案。
HTTP1.1 - ETag、If-None-Match
伺服器返回 ETag
用於標記檔案,當 ETag
修改時表示檔案被修改。(如:etag: 2e681a-6-5d044840
)
瀏覽器請求時會傳送 If-None-Match
和上一次返回的 ETag
,伺服器根據兩次 ETag
判斷是否是最新檔案。
禁止快取
請求時可以禁止快取,cache-control: no-cache, no-store
。
no-cache
表示每次請求資源都會向瀏覽器傳送請求(即取消強快取),no-store
取消快取。
public 和 private
Cache-Control
可以指定 public
或 private
,private
表示為使用者個人資訊,不能在快取伺服器快取。
9. HTTP 支援方法
GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT
10. GET 和 POST 區別
【前端 · 面試 】HTTP 總結(五)—— GET 和 POST
- GET 多用於從服務端獲取資源,POST 一般用來向服務端提交資源
- GET 一般用URL傳參,由於 URL 長度限制引數長度有限制,POST 引數可以放在 body 中,無長度限制。
- 引數的資料型別,GET 只接受 ASCII 字元,而 POST 沒有限制。
- GET 請求只能進行 URL 編碼,POST 支援多種編碼方式。
- GET 請求會被瀏覽器主動 cache,而 POST 不會,除非手動設定。
11. 在位址列裡輸入一個 URL,到這個頁面呈現出來,中間會發生什麼?
- DNS 解析
域名解析為 IP 地址,瀏覽器快取-->作業系統快取-->訪問 DNS 伺服器 - TCP 連線
三次握手、四次揮手 - HTTP 請求
強快取、協商快取 - 服務端處理請求,HTTP 響應返回
返回碼 - 瀏覽器拿到響應資料,解析響應內容,把解析的結果展示給使用者
DOM樹、CSSOM樹、Render樹、迴流、重繪
12. XSS 和 CSRF
前端安全系列(一):如何防止XSS攻擊?
前端安全系列之二:如何防止CSRF攻擊?
XSS
Cross-Site Scripting(跨站指令碼攻擊) 簡稱 XSS,是一種程式碼注入攻擊。攻擊者通過在目標網站上注入惡意指令碼,使之在使用者的瀏覽器上執行。利用這些惡意指令碼,攻擊者可獲取使用者的敏感資訊如 Cookie、SessionID 等,進而危害資料安全。
XSS 的本質是:惡意程式碼未經過濾,與網站正常的程式碼混在一起;瀏覽器無法分辨哪些指令碼是可信的,導致惡意指令碼被執行。
XSS 分類
根據攻擊的來源,XSS 攻擊可分為儲存型、反射型和 DOM 型三種。
型別 | 儲存區* | 插入點* |
---|---|---|
儲存型 XSS | 後端資料庫 | HTML |
反射型 XSS | URL | HTML |
DOM 型 XSS | 後端資料庫/前端儲存/URL | 前端 JavaScript |
- 儲存區:惡意程式碼存放的位置。
- 插入點:由誰取得惡意程式碼,並插入到網頁上。
前兩種屬於伺服器安全漏洞,DOM 型 XSS 由前端取出惡意程式碼並執行,屬於前端漏洞。
XSS 攻擊的預防
- 輸入過濾
- 改成純前端渲染,把程式碼和資料分隔開
- 不要把不可信的資料作為 HTML 插到頁面上、對 HTML 做充分轉義
- 不要在 JavaScript 中執行不信任的字串,比如
eval()
- Content Security Policy、輸入內容長度控制、
HTTP-only Cookie
、驗證碼
CSRF
CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站傳送跨站請求。利用受害者在被攻擊網站已經獲取的註冊憑證,繞過後臺的使用者驗證,達到冒充使用者對被攻擊的網站執行某項操作的目的。CSRF 攻擊針對狀態改變請求,而不是盜竊資料,因為攻擊者無法檢視對偽造請求的響應。
典型攻擊方式:在 b.com 向 a.com 傳送請求,會帶上 a.com 的 cookie。
CSRF的特點
- 攻擊一般發起在第三方網站,而不是被攻擊的網站。
- 攻擊利用受害者在被攻擊網站的登入憑證,冒充受害者提交操作;而不是直接竊取資料。
- 整個過程攻擊者並不能獲取到受害者的登入憑證,僅僅是“冒用”。
- 跨站請求可以用各種方式:圖片URL、超連結、CORS、Form提交等等。部分請求方式可以直接嵌入在第三方論壇、文章中,難以進行追蹤。
防護策略
- 同源檢測:通過 Origin Header 或 Referer Header 確定來源域名
- CSRF Token
- 雙重Cookie驗證
- Samesite Cookie屬性:Samesite=Strict 表示 cookie 不可作為第三方 cookie
13. Cookie/Session/sessionStorage/localStorage/IndexDB
- Cookie 資料始終在同源的 HTTP 請求中攜帶(即使不需要),即 Cookie 在瀏覽器和伺服器間來回傳遞。而 sessionStorage 和 localStorage 不會自動把資料發給伺服器,僅在本地儲存。Cookie 資料還有路徑(path)的概念,可以限制 Cookie 只屬於某個路徑下,儲存的大小很小隻有4K左右。
- sessionStorage 僅在當前瀏覽器視窗關閉前有效,localStorage 始終有效,視窗或瀏覽器關閉也一直儲存,因此用作持久資料,Cookie 只在設定的 Cookie 過期時間之前一直有效,即使視窗或瀏覽器關閉。
- localStorage 和 Cookie 在所有同源視窗中都是共享的。但是不同頁面或標籤頁間無法共享 sessionStorage 的資訊。
- IndexDB 是一個執行在瀏覽器上的非關係型資料庫。理論上來說,IndexDB 是沒有儲存上限的(一般來說不會小於 250M)。它不僅可以儲存字串,還可以儲存二進位制資料。
- Session 是儲存在伺服器的鍵值對,一般把 SessionId 存在 Cookie 中,通過 SessionId 可以查詢對應物件。
14. SSO 單點登入
前端鑑權的兄弟們:cookie、session、token、jwt、單點登入
cookie
在提供標記的介面,通過 HTTP 返回頭的 Set-Cookie 欄位,直接「種」到瀏覽器上;瀏覽器發起請求時,會自動把 cookie 通過 HTTP 請求頭的 Cookie 欄位,帶給介面
- Domain / Path 限制 cookie 的域名/路徑
- Expires / Max-Age 指定 cookie 的有效期
- Secure / HttpOnly Secure 屬性指定瀏覽器只有在加密協議 HTTPS 下,才能將這個 Cookie 傳送到伺服器。HttpOnly 屬性指定該 Cookie 無法通過 JavaScript 指令碼拿到。
- HTTP 頭對 cookie 的讀寫 一個 Set-Cookie 頭用於向瀏覽器寫入一條 cookie,設定多個 cookie 需要設定多條
Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Session
- 使用者登入,服務端把使用者登入狀態存為 Session,生成一個 sessionId,把 sessionId set 到 cookie 上
- session 儲存方式,記憶體、資料庫、Redis
Token
- 把登入資訊加密存為 token,並 set 到 cookie 中,介面校驗 token 有效性。
- JSON Web Token (JWT) 是一個開放標準,定義了一種傳遞 JSON 資訊的方式。這些資訊通過數字簽名確保可信。
access token
用來訪問業務介面,由於有效期足夠短,盜用風險小,也可以使請求方式更寬鬆refresh token
用來獲取access token
,有效期可以長一些,通過獨立服務和嚴格的請求方式增加安全性;由於不常驗證,也可以如前面的 session 一樣處理
單點登入 (SSO, Single Sign On)
- 使用者進入 A 系統,沒有登入憑證(ticket),A 系統給他跳到 SSO
- SSO 沒登入過,也就沒有 sso 系統下沒有憑證(注意這個和前面 A ticket 是兩回事),輸入賬號密碼登入
- SSO 賬號密碼驗證成功,通過介面返回做兩件事:一是種下 sso 系統下憑證(記錄使用者在 SSO 登入狀態);二是通過一個帶 code 的 URL 重定向到系統 A 的介面上,這個介面通常在 A 向 SSO 註冊時約定
- 瀏覽器被重定向到 A 域下,帶著 code 訪問了 A 的 callback 介面,callback 介面通過 code 換取 ticket
- 這個 code 不同於 ticket,code 是一次性的,暴露在 URL 中,只為了傳一下換 ticket,換完就失效
- callback 介面拿到 ticket 後,在自己的域下 set cookie 成功
- 客戶端拿到 ticket,儲存起來,帶著請求系統 A 介面
- 系統 A 校驗 ticket,成功後正常處理業務請求
- 此時使用者第一次進入系統 B,沒有登入憑證(ticket),B 系統給他跳到 SSO
- SSO 登入過,統一順序訪問 B 系統
15. 跨域問題
同源策略 SOP(Same origin policy)
同源指:協議相同、域名相同、埠相同。如果非同源,共有三種行為受到限制:
- Cookie、LocalStorage 和 IndexDB 無法讀取。
- DOM 和 JS 物件無法獲得
- AJAX 請求不能傳送。
跨域解決方案
- JSONP
- WebSocket
- CORS
- 代理
跨域資源共享 CORS
瀏覽器將 CORS 請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
簡單請求
滿足下面兩個條件的是簡單請求:
- 請求方法是以下三種方法之一:HEAD、GET、POST
- HTTP的頭資訊不超出以下幾種欄位:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
瀏覽器發現這次跨源AJAX請求是簡單請求,就自動在頭資訊之中,新增一個 Origin
欄位,用來說明,本次請求來自哪個源(協議 + 域名 + 埠)。伺服器根據這個值,決定是否同意這次請求。
伺服器返回:
Access-Control-Allow-Origin: *
表示接受的域名,*
表示任意域名Access-Control-Allow-Credentials: true
表示是否允許傳送CookieAccess-Control-Expose-Headers
指定前端可以獲取的返回頭欄位
withCredentials
如果前端要傳送 cookie
需要指定
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
同時伺服器需要設定 Access-Control-Allow-Credentials: true
且 Access-Control-Allow-Origin
不能為 *
。
非簡單請求
不滿足簡單請求條件的為非簡單請求。非簡單請求的 CORS 請求,會在正式通訊之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。
瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些 HTTP 動詞和頭資訊欄位。只有得到肯定答覆,瀏覽器才會發出正式的 XMLHttpRequest
請求,否則就報錯。
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
服務端返回
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000 # 可選,用來指定本次預檢請求的有效期,單位為秒