詳解HTTP/HTTPS(一)——HTTP協議

HTTP/HTTPS協議無疑是面試中最常問的幾個計網協議之一。然而網上很多博客都寫得偏簡略,不夠全面。於是我便打算把最近我自己整理的資料整合起來,希望能夠幫助到大家。內容較多,大致會分爲三篇博客,一篇介紹HTTP協議,一篇介紹SSL/TLS協議,一篇介紹HTTPS協議。

HTTP協議也叫超文本傳輸協議,它定義了客戶端和服務器的通信格式。是一種基於請求和響應、無狀態的應用層協議。傳輸層採用TCP協議,具備可靠的數據傳輸。接下來我們便從HTTP請求、HTTP響應、版本更替三個方面來看一下HTTP。

一、HTTP請求

(一)、定義

HTTP請求是客戶端往服務端發送請求動作,告知服務器自己的要求。

(二)、數據報格式

HTTP請求數據格式由請求行、請求頭部和請求主體三部分組成:

1、狀態行:包括請求方式Method、資源路徑URL、協議版本Version;

2、請求頭:包括一些訪問的域名、用戶代理、Cookie等信息;

3、請求正文:就是HTTP請求的數據。

(三)、補充知識點

1、請求方法的種類

GET   --- 訪問服務器的資源

POST  --- 向服務器發送要修改的數據

HEAD  --- 獲取服務器文檔的首部

PUT   --- 向服務器上傳資源

DELETE --- 刪除服務器的資源

2、GET和POST的區別

#get一般用於從服務器上獲取數據,post一般用於向服務器傳送數據

#請求的時候參數的位置有區別,get的參數是拼接在url後面,用戶在瀏覽器地址欄可以看到。post是放在http包的包體中。

#能提交的數據有區別,get方式能提交的數據只能是文本,且大小不超過1024個字節,而post不僅可以提交文本還有二進制文件。

二、HTTP響應

(一)、定義

服務器收到了客戶端發來的HTTP請求後,根據HTTP請求中的動作要求,服務端做出具體的動作,並將結果迴應給客戶端,稱爲HTTP響應。

(二)、數據報格式

HTTP響應由三部分組成:響應行、響應頭部和響應主體;

1、狀態行:包括協議版本Version、狀態碼Status Code、迴應短語;

2、響應頭:包括搭建服務器的軟件,發送響應的時間,迴應數據的格式等信息;

3、響應正文:就是響應的具體數據。

(三)、補充知識點

1、五種響應狀態碼

1開頭的表示HTTP請求已經接受,繼續處理請求

2開頭的表示HTTP請求已經處理完成

3開頭的表示把請求訪問的URL重定向到其他目錄

4開頭的表示客戶端出現錯誤

5開頭的表示服務端出現錯誤

常見的幾種狀態碼含義如下

        200---/請求已經正常處理完畢

        301---/請求永久重定向

        302---/請求臨時重定向

        304---/請求被重定向到客戶端本地緩存

        400---/客戶端請求存在語法錯誤

        401---/客戶端請求沒有經過授權

        403---/客戶端的請求被服務器拒絕,一般爲客戶端沒有訪問權限

        404---/客戶端請求的URL在服務端不存在

        500---/服務端永久錯誤

        503---/服務端發生臨時錯誤

 

三、HTTP的版本更替

(一)、HTTP0.9

HTTP協議的最初版本,功能簡陋,僅支持請求方式GET,並且僅能請求訪問HTML格式的資源。

(二)、HTTP1.0

在0.9版本上做了改進,一是增加了請求方式POST和HEAD;二是資源不再侷限於HTML格式(content-type首部行);三是開始支持cache,當客戶端在規定時間內訪問同一網站,直接訪問cache即可。

但是1.0版本的工作方式是每次TCP連接只能發送一個請求,當服務器響應後就會關閉這次連接,下一個請求需要再次建立TCP連接。即採用非持續性連接,不支持keepalive。非持續性連接存在兩個缺點,一是必須對所有的對象都維護一條全新的連接,在客戶端和服務器都要分配TCP的緩存區和TCP變量,給服務器帶來嚴重的負擔。二是所有的請求對象都要經受兩倍RTT的時延。

(三)、HTTP1.1

在1.0的版本上做了改進,一是解決了1.0版本非持續性連接的問題,1.1版本加入了持續性連接(connection首部行,keep-alive),一個TCP連接可以允許多個發送HTTP請求;二是加入了管道機制,一個TCP連接允許多個請求同時發送,增加了併發性;(舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接裏面,先發送A請求,然後等待服務器做出迴應,收到後再發出B請求。管道機制則是允許瀏覽器同時發出A請求和B請求,但是服務器還是按照順序,先回應A請求,完成後再回應B請求。)三是新增了請求方式PUT、PATCH(更新資源)、DELETE等。四是支持斷點續傳。HTTP

但是它也仍然存在着一些問題,一個是服務端是按隊列順序處理請求的,假如一個請求處理時間很長,則會導致後邊的請求無法處理,這樣就造成了隊頭阻塞的問題;同時HTTP是無狀態的連接,因此每次請求都需要添加重複的字段,降低了帶寬的利用率。

(四)、HTTP2.0 

爲了解決1.1版本利用率不高的問題,提出了HTTP/2.0版本。所做的改進主要有三個。

一是增加雙工模式,即不僅客戶端能夠同時發送多個請求,服務端也能同時處理多個請求,解決了HTTP request級別的隊頭堵塞問題;

二是對字段頭部進行壓縮。HTTP請求和響應中,狀態行和請求/響應頭都是些信息字段,並沒有真正的數據,因此在2.0版本中將所有的信息字段建立一張表,爲表中的每個字段建立索引,客戶端和服務端共同使用這個表,他們之間就以索引號來表示信息字段,這樣就避免了1.1舊版本重複繁瑣的字段,並以壓縮的方式傳輸,提高利用率。

三是另外也增加服務器推送的功能,即不經請求服務端主動向客戶端發送數據。

至於HTTP3.0,我們放到最後再來介紹,相較於前幾個版本,它已經發生了巨大的變化了。

四、其他常見的問題

(一)、HTTP協議如何處理粘包問題

HTTP採用TCP進行通信,而TCP是面向數據流傳輸的,容易出現粘包問題。HTTP採用的解決方案主要有兩個:

1、content-length字段

content-length字段聲明瞭本次迴應的數據長度。TCP協議保證了數據能夠按序交付,結合content-length字段即可劃分數據包所屬的迴應。但是使用content-length字段的前提條件是,服務器在發送迴應前必須知道迴應數據的長度。對於一些很耗時的操作來說,這意味着服務器要等到所有操作完成,才能發送數據,顯然這樣的效率不高。

2、Transfer-Encoding字段

Transfer-Encoding,即分塊傳輸編碼,採用“流模式”,產生一塊數據就發送一塊,效率更高。只要請求或迴應的頭信息有Transfer-Encoding字段,就表明迴應將由數量未定的數據塊組成。每個非空的數據塊之前,會有一個16進制的數值,表示這個塊的長度。最後是一個大小爲0的塊,就表示本次迴應的數據發送完了。

(二)、HTTP協議無狀態的解決方案——身份認證機制

1、BASIC認證

#基本認證步驟:

A、客戶端訪問一個受http基本認證保護的資源。

B、服務器返回401狀態,要求客戶端提供用戶名和密碼進行認證。(驗證失敗的時候,響應頭會加上WWW-Authenticate: Basic realm="請求域"。)

401 Unauthorized

WWW-Authenticate: Basic realm="WallyWorld"

C、客戶端將輸入的用戶名密碼用Base64進行編碼後,採用非加密的明文方式傳送給服務器。

Authorization: Basic xxxxxxxxxx.

D、服務器將Authorization頭中的用戶名密碼解碼並取出,進行驗證,如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。

#特點

A、Http是無狀態的,同一個客戶端對同一個realm內資源的每一個訪問會被要求進行認證。

B、客戶端通常會緩存用戶名和密碼,並和authentication realm一起保存,所以,一般不需要你重新輸入用戶名和密碼。

C、以非加密的明文方式傳輸,雖然轉換成了不易被人直接識別的字符串,但是無法防止用戶名密碼被惡意盜用。雖然用肉眼看不出來,但用程序很容易解密。

2、摘要認證digest authentication

#這個認證可以看做是基本認證的增強版本,不包含密碼的明文傳遞。即客戶端通過某種哈希算法計算出自身用戶名和密碼的哈希值(即又叫response值),然後將其發送給服務器進行身份驗證。因爲服務器擁有與客戶端同樣的信息,因此服務器可以進行同樣的計算,以驗證客戶端提交的 response 值的正確性。並且由於哈希計算是不可逆的,即理論上通過response值來逆推出用戶名和密碼是不可能的,因此提高了通信的安全性。

#response值的計算

主要分爲三步。其中當多個數值合併的時候,使用冒號作爲分割符:

A、對用戶名、認證域(realm)以及密碼的合併值計算 MD5 哈希值,結果稱爲 HA1。

B、對HTTP方法以及URI的摘要的合併值計算 MD5 哈希值,例如,"GET" 和 "/dir/index.html",結果稱爲 HA2。

C、對HA1、服務器密碼隨機數(nonce)、請求計數(nc)、客戶端密碼隨機數(cnonce)、保護質量(qop)以及 HA2 的合併值計算 MD5 哈希值。結果即爲客戶端提供的response 值。

3、cookie/session 認證

用戶輸入用戶名和密碼發起請求,服務器認證通過後分配一個唯一的SESSIONID發送給客戶端。當客戶端發起新的請求的時候,將攜帶上這個SESSIONID來表明自己的身份。這樣服務器便能夠找到這個客戶端對應的Session。默認的,當我們關閉瀏覽器的時候,客戶端cookie會被刪除,可以通過修改cookie 的expire time使cookie在一定時間內有效。但是服務器端的session不會被銷燬,除非通過invalidate或超時。

補充:cookie和session的區別:兩者都是用於記錄客戶端狀態的機制。cookie將客戶端狀態(比如用戶賬號和密碼)保存在本地的一個txt文件中,session則是把用戶賬號和密碼信息保存在服務器上,客戶端保存的只是sessionID。從安全性上來看,session的用戶賬號和密碼存儲在服務器上,會比cookie更安全,但是兩者都無法避免會話被劫持的問題。從性能上來看,session由於把客戶狀態信息保存在了服務器上,從而佔用了一定了內存,性能不如cookie好。

4、Token 認證

#Token認證可以看做是cookie/session認證的增強,它新增了簽名字段防止信息被篡改,並將獲取到的客戶端信息用非對稱加密算法進行加密後,得到一個token,再把Token存儲在數據庫中。

#認證過程

token認證和cookie認證差不多,

A、首次登陸,用戶名和密碼驗證過之後,將sessionId保存在token中,或者將一個key保存在token中,key的值可以設置爲用戶唯一性的信息(賬號/密碼/身份認證機制(電話號/身份證號/支付寶賬號/銀行卡信息)...);設置token的有效期,並保存在服務器數據庫中;

B、服務器將這個token值返回給客戶端,客戶端拿到 token 值之後,將 token 保存在 cookie 中,以後客戶端再次發送網絡請求(一般不是登錄請求)的時候,就會將這個 token 值附帶到參數中發送給服務器。服務器接收到客戶端的請求之後,會取出token值與保存在本地(數據庫)中的token值做對比!
C、如果兩個 token 值相同 :說明用戶登錄成功過!當前用戶處於登錄狀態!如果沒有這個token或者過期,則設置token爲無效,並讓用戶重新登錄。

#優點

A、減輕服務器壓力:通過token可以將用戶的基本信息(非隱私的,比如UserId,過期時間,生成的隨機key等)全部加密簽名後放入token中,從而服務器端不需要保存用戶登錄信息,大大減輕服務器壓力。

B、用戶認證完全靠token識別,通過簽名來保證token沒有被修改過(只有服務器才知道祕鑰,比如常見的非對稱加密算法),是服務器下發的token。

C、支持跨域訪問:因爲服務器並沒有保存登錄狀態,完全靠簽名的token識別,那麼另一個網站只要有對應的私鑰,就可以對token驗證,前提是傳輸的用戶認證信息通過HTTP頭傳輸;

D、更適用CDN: 可以通過內容分發網絡請求你服務端的所有資料(如:javascript,HTML,圖片等),因爲不需要同步服務器上的登錄狀態信息;(CDN是未來一個很重要的發展方向)

E、性能更好: 因爲從token中可以獲得userId,不用查詢登錄狀態表;

(三)、Web緩存與條件GET

Web緩存服務器位於客戶和Web服務器之間。它有自己的磁盤存儲空間,能夠在存儲空間中保存最近請求過對象的副本。當客戶下次再請求相同副本時,便可以直接從Web緩存器中獲得。並且Web緩存器通過條件GET機制來保證客戶能夠取到最新的對象。舉例來說,假設當前瀏覽器正在請求一個對象,將會發生如下情況:

A、瀏覽器創建一個到Web緩存器的TCP連接,並向Web緩存器發送一個關於該對象的HTTP請求;

B、Web緩存器接收到HTTP請求後,查看本地是否有被請求對象的副本。假設該對象是一個新對象,Web緩存器沒有該對象的副本。那麼Web緩存器將會打開一個到該對象初始服務器的TCP連接,並向其發送一個關於該對象的HTTP請求。

C、Web服務器接收到該請求後,發送一個具有該對象及最後修改時間(即Last-modified字段)的HTTP響應

D、Web緩存器接收到響應後,在本地存儲空間存儲一份該對象的副本及其Last-modified的值,並向客戶的瀏覽器發送該副本。

之後如果有其他瀏覽器再次向該Web緩存服務器請求該對象時,由於Web緩存器在本地查找到了該對象的副本,它會先給Web服務器發送一個條件GET執行最新檢查。該請求報文包含請求對象和對象最後被修改的時間(If-modified-since字段)。該條件GET告訴服務器僅當在指定日期後該對象被修改過才發送該對象。Web服務器會進行相應判斷,如果該對象在指定日期之後沒有再被修改,則發送一個帶有Not Modified短語的響應報文,不包含該對象。否則則發送一個帶有新的對象及新的Last-modified值的響應報文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章