HTTP

一、Http報(bào)文

http報(bào)文可以分為請求報(bào)文和響應(yīng)報(bào)文,格式大同小異。主要分為三個(gè)部分:
(1)起始行
(2) 首部
(3) 主體
請求報(bào)文格式:
<method> <request-url> <version>
<headers>

<entity-body>

響應(yīng)報(bào)文格式:
<version> <status> <reason-phrase>
<headers>

<entity-body>
從請求報(bào)文格式和響應(yīng)報(bào)文格式可以看出,兩者主要在起始行上有差異。這里稍微解釋一下各個(gè)標(biāo)簽:
<method> 指請求方法,常用的主要是Get、 Post、Head 還有其他一些我們這里就不說了,有興趣的可以自己查閱一下

<version> 指協(xié)議版本,現(xiàn)在通常都是Http/1.1了

<request-url> 請求地址

<status> 指響應(yīng)狀態(tài)碼, 我們熟悉的200、404等等

<reason-phrase> 原因短語,200 OK 、404 Not Found 這種后面的描述就是原因短語,通常不必太關(guān)注。

二、method

GET和POST兩個(gè)方法之間在傳輸形式上有一些區(qū)別,通過Get方法發(fā)起請求時(shí),會(huì)將請求參數(shù)拼接在request-url尾部,格式是url?param1=xxx&param2=xxx&[…]。

我們需要知道,這樣傳輸參數(shù)會(huì)使得參數(shù)都暴露在地址欄中。并且由于url是ASCII編碼的,所以參數(shù)中如果有Unicode編碼的字符,例如漢字,都會(huì)編碼之后傳輸。另外值得注意的是,雖然http協(xié)議并沒有對url長度做限制,但是一些瀏覽器和服務(wù)器可能會(huì)有限制,所以通過GET方法發(fā)起的請求參數(shù)不能夠太長。而通過POST方法發(fā)起的請求是將參數(shù)放在請求體中的,所以不會(huì)有GET參數(shù)的這些問題。

另外一點(diǎn)差別就是方法本身的語義上的。GET方法通常是指從服務(wù)器獲取某個(gè)URL資源,其行為可以看作是一個(gè)讀操作,對同一個(gè)URL進(jìn)行多次GET并不會(huì)對服務(wù)器產(chǎn)生什么影響。而POST方法通常是對某個(gè)URL進(jìn)行添加、修改,例如一個(gè)表單提交,通常會(huì)往服務(wù)器插入一條記錄。多次POST請求可能導(dǎo)致服務(wù)器的數(shù)據(jù)庫中添加了多條記錄。所以從語義上來講,兩者也是不能混為一談的。
概括:
1、GET請求會(huì)將請求參數(shù)拼接在request-url尾部,POST放在請求體中;
2、GET請求需要對參數(shù)中的中文編碼之后傳輸;
3、有些瀏覽器和服務(wù)器可能會(huì)對url長度有限制,如果請求參數(shù)過長,那么就得使用POST請求方法;
4、GET方法通常是指從服務(wù)器獲取某個(gè)URL資源,可以看做讀操作;而POST方法通常是對某個(gè)URL進(jìn)行添加、修改,通常會(huì)往服務(wù)器插入一條記錄。

三、狀態(tài)碼

常見的狀態(tài)碼主要有
200 OK 請求成功,實(shí)體包含請求的資源。
301 Moved Permanent 請求的URL被移除了,通常會(huì)在Location首部中包含新的URL用于重定向。
304 Not Modified 條件請求進(jìn)行再驗(yàn)證,資源未改變。
404 Not Found 資源不存在
206 Partial Content 成功執(zhí)行一個(gè)部分請求。這個(gè)在用于斷點(diǎn)續(xù)傳時(shí)會(huì)涉及到。

四、header

在請求報(bào)文和響應(yīng)報(bào)文中都可以攜帶一些信息,通過與其他部分配合,能夠?qū)崿F(xiàn)各種強(qiáng)大的功能。這些信息位于起始行之下與請求實(shí)體之間,以鍵值對的形式,稱之為首部。每條首部以回車換行符結(jié)尾,最后一個(gè)首部額外多一個(gè)換行,與實(shí)體分隔開。

這里我們重點(diǎn)關(guān)注一下
Date
Cache-Control
Last-Modified
Etag
Expires
If-Modified-Since
If-None-Match
If-Unmodified-Since
If-Range
If-Match

Http的首部還有很多,但限于篇幅我們不一一討論。這些首部都是Http緩存會(huì)涉及到的,在下文中我們會(huì)來說說各自的作用。

五、實(shí)體

請求發(fā)送的資源,或是響應(yīng)返回的資源。

六、Http緩存

緩存:將http請求服務(wù)器獲取到的資源副本存到本地,下次對該url資源請求的時(shí)候,快速的從本地存儲(chǔ)設(shè)備中獲取到該url資源。
優(yōu)點(diǎn):既可以節(jié)約不必要的網(wǎng)絡(luò)帶寬,又能迅速對http請求做出響應(yīng)。
先擺出幾個(gè)概念: 1、新鮮度檢測 2、再驗(yàn)證 3、再驗(yàn)證命中
時(shí)間差異:有些url所對應(yīng)的資源并不是一成不變的,服務(wù)器中該url的資源可能在一定時(shí)間之后會(huì)被修改。這時(shí)本地緩存中的資源將與服務(wù)器一側(cè)的資源有差異。

新鮮度檢測:既然在一定時(shí)間之后可能資源會(huì)改變,那么在某個(gè)時(shí)間之前我們可以認(rèn)為這個(gè)資源沒有改變,從而放心大膽的使用緩存資源,當(dāng)請求時(shí)間超過來該時(shí)間,我們認(rèn)為這個(gè)緩存資源可能不再與服務(wù)器端一致了。所以當(dāng)我們發(fā)起一個(gè)請求時(shí),我們需要先對緩存的資源進(jìn)行判斷,看看究竟我們是否可以直接使用該緩存資源,這個(gè)就叫做新鮮度檢測。即每個(gè)資源就像一個(gè)食品一樣,擁有一個(gè)過期時(shí)間,我們吃之前需要先看看有沒有過期。
再驗(yàn)證:如果發(fā)現(xiàn)該緩存資源已經(jīng)超過了一定的時(shí)間,我們再次發(fā)起請求時(shí)不會(huì)直接將緩存資源返回,而是先去服務(wù)器查看該資源是否已經(jīng)改變,這個(gè)就叫做再驗(yàn)證。
再驗(yàn)證命中:如果服務(wù)器發(fā)現(xiàn)對應(yīng)的url資源并沒有發(fā)生變化,則會(huì)返回304 Not Modified,并且不再返回對應(yīng)的實(shí)體。這稱之為再驗(yàn)證命中。相反如果再驗(yàn)證未命中,則返回200 OK,并將改變后的url資源返回,此時(shí)緩存可以更新以待之后請求。
1、新鮮度檢測 我們需要通過檢測資源是否超過一定的時(shí)間,來判斷緩存資源是否新鮮可用。那么這個(gè)一定的時(shí)間怎么決定呢?其實(shí)是由服務(wù)器通過在響應(yīng)報(bào)文中增加Cache-Control:max-age,或是Expire這兩個(gè)首部來實(shí)現(xiàn)的。值得注意的是Cache-Control是http1.1的協(xié)議規(guī)范,通常是接相對的時(shí)間,即多少秒以后,需要結(jié)合last-modified這個(gè)首部計(jì)算出絕對時(shí)間。而Expire是http1.0的規(guī)范,后面接一個(gè)絕對時(shí)間。 2、再驗(yàn)證 如果通過新鮮度檢測發(fā)現(xiàn)需要請求服務(wù)器進(jìn)行再驗(yàn)證,那么我們至少需要告訴服務(wù)器,我們已經(jīng)緩存了一個(gè)什么樣的資源了,然后服務(wù)器來判斷這個(gè)緩存資源到底是不是與當(dāng)前的資源一致。邏輯是這樣沒錯(cuò)。那怎么告訴服務(wù)器我當(dāng)前已經(jīng)有一個(gè)備用的緩存資源了呢?我們可以采用一種稱之為條件請求的方式實(shí)現(xiàn)再驗(yàn)證。 3、Http定義了5個(gè)首部用于條件請求: If-Modified-Since If-None-Match If-Unmodified-Since If-Range If-Match
If-Modified-Since 可以結(jié)合Last-Modified這個(gè)服務(wù)器返回的響應(yīng)首部使用,當(dāng)我們發(fā)起條件請求時(shí),將Last-Modified首部的值作為If-Modified-Since首部的值傳遞到服務(wù)器,意思是查詢服務(wù)器的資源自從我們上一次緩存之后是否有修改。

If-None-Match 需要結(jié)合另一個(gè)Etag的服務(wù)器返回的響應(yīng)首部使用。Etag首部實(shí)際上可以認(rèn)為是服務(wù)器對文檔資源定義的一個(gè)版本號。有時(shí)候一個(gè)文檔被修改了,可能所做的修改極為微小,并不需要所有的緩存都重新下載數(shù)據(jù)?;蛘哒f某一個(gè)文檔的修改周期極為頻繁,以至于以秒為時(shí)間粒度的判斷已經(jīng)無法滿足需求。這個(gè)時(shí)候可能就需要Etag這個(gè)首部來表明這個(gè)文檔的版號了。發(fā)起條件請求時(shí)可將緩存時(shí)保存下來的Etag的值作為If-None-Match首部的值發(fā)送至服務(wù)器,如果服務(wù)器的資源的Etag與當(dāng)前條件請求的Etag一致,表明這次再驗(yàn)證命中。

其他三個(gè)與斷點(diǎn)續(xù)傳涉及到的相關(guān)知識有關(guān),本文暫時(shí)不討論。待我之后寫一篇文章來講講斷點(diǎn)續(xù)傳。

七、OkHttp的緩存

OkHttp緩存流程總結(jié):
1、從接收到的請求中,解析出Url和各個(gè)首部。 2、查詢本地是否有緩存副本可以使用。 3、如果有緩存,則進(jìn)行新鮮度檢測,如果緩存足夠新鮮,則使用緩存作為響應(yīng)返回,如果不夠新鮮了,則構(gòu)造條件請求,發(fā)往服務(wù)器再驗(yàn)證。如果沒有緩存,就直接將請求發(fā)往服務(wù)器。 4、把從服務(wù)器返回的響應(yīng),更新或是新增到緩存中。

八、OAuth

OAuth是一個(gè)用于授權(quán)第三方獲取相應(yīng)資源的協(xié)議。與以往的授權(quán)方式不同的是,OAuth的授權(quán)能避免用戶暴露自己的用戶密碼給第三方,從而更加的安全。OAuth協(xié)議通過設(shè)置一個(gè)授權(quán)層,以區(qū)分用戶和第三方應(yīng)用。用戶本身可以通過用戶密碼登陸服務(wù)提供商,獲取到賬戶所有的資源。而第三方應(yīng)用只能通過向用戶請求授權(quán),獲取到一個(gè)Access Token,用以登陸授權(quán)層,從而在指定時(shí)間內(nèi)獲取到用戶授權(quán)訪問的部分資源。


OAuth角色.png

從上圖可以看出,一個(gè)OAuth授權(quán)的流程主要可以分為6步:
1、客戶端向用戶申請授權(quán)。
2、用戶同意授權(quán)。
3、客戶端通過獲取的授權(quán),向認(rèn)證服務(wù)器申請Access Token。
4、認(rèn)證服務(wù)器通過授權(quán)認(rèn)證后,下發(fā)Access Token。
5、客戶端通過獲取的到Access Token向資源服務(wù)器發(fā)起請求。
6、資源服務(wù)器核對Access Token后下發(fā)請求資源。

九、Https

簡單的說 Http + 加密 + 認(rèn)證 + 完整性保護(hù) = Https

傳統(tǒng)的Http協(xié)議是一種應(yīng)用層的傳輸協(xié)議,Http直接與TCP協(xié)議通信。其本身存在一些缺點(diǎn):
1、Http協(xié)議使用明文傳輸,容易遭到竊聽。
2、Http對于通信雙方都沒有進(jìn)行身份驗(yàn)證,通信的雙方無法確認(rèn)對方是否是偽裝的客戶端或者服務(wù)端。
3、Http對于傳輸內(nèi)容的完整性沒有確認(rèn)的辦法,往往容易在傳輸過程中被劫持篡改。
因此,在一些需要保證安全性的場景下,比如涉及到銀行賬戶的請求時(shí),Http無法抵御這些攻擊。
Https則可以通過增加的SSL\TLS,支持對于通信內(nèi)容的加密,以及對通信雙方的身份進(jìn)行驗(yàn)證。

十、Https的加密

近代密碼學(xué)中加密的方式主要有兩類:
1、對稱秘鑰加密
2、非對稱秘鑰加密

對稱秘鑰加密是指加密與解密過程使用同一把秘鑰。這種方式的優(yōu)點(diǎn)是處理速度快,但是如何安全的從一方將秘鑰傳遞到通信的另一方是一個(gè)問題。

非對稱秘鑰加密是指加密與解密使用兩把不同的秘鑰。這兩把秘鑰,一把叫公開秘鑰,可以隨意對外公開。一把叫私有秘鑰,只用于本身持有。得到公開秘鑰的客戶端可以使用公開秘鑰對傳輸內(nèi)容進(jìn)行加密,而只有私有秘鑰持有者本身可以對公開秘鑰加密的內(nèi)容進(jìn)行解密。這種方式克服了秘鑰交換的問題,但是相對于對稱秘鑰加密的方式,處理速度較慢。

SSL\TLS的加密方式則是結(jié)合了兩種加密方式的優(yōu)點(diǎn)。首先采用非對稱秘鑰加密,將一個(gè)對稱秘鑰使用公開秘鑰加密后傳輸?shù)綄Ψ健Ψ绞褂盟接忻罔€解密,得到傳輸?shù)膶ΨQ秘鑰。之后雙方再使用對稱秘鑰進(jìn)行通信。這樣即解決了對稱秘鑰加密的秘鑰傳輸問題,又利用了對稱秘鑰的高效率來進(jìn)行通信內(nèi)容的加密與解密。
對稱加密和非對稱加密的區(qū)別:1、對稱加密(加密和解密用同一個(gè)秘鑰)處理速度快,非對稱處理速度慢;2、對稱加密秘鑰傳輸過程中容易被篡改,安全系數(shù)低;非對稱加密分公鑰和私鑰,安全系數(shù)相對較高。

十一、Https的認(rèn)證

SSL\TLS采用的混合加密的方式還是存在一個(gè)問題,即怎么樣確保用于加密的公開秘鑰確實(shí)是所期望的服務(wù)器所分發(fā)的呢?也許在收到公開秘鑰時(shí),這個(gè)公開秘鑰已經(jīng)被別人篡改了。因此,我們還需要對這個(gè)秘鑰進(jìn)行認(rèn)證的能力,以確保我們通信的對方是我們所期望的對象。

目前的做法是使用由數(shù)字證書認(rèn)證機(jī)構(gòu)頒發(fā)的公開秘鑰證書。服務(wù)器的運(yùn)營人員可以向認(rèn)證機(jī)構(gòu)提出公開秘鑰申請。認(rèn)證機(jī)構(gòu)在審核之后,會(huì)將公開秘鑰與共鑰證書綁定。服務(wù)器就可以將這個(gè)共鑰證書下發(fā)給客戶端,客戶端在收到證書后,使用認(rèn)證機(jī)構(gòu)的公開秘鑰進(jìn)行驗(yàn)證。一旦驗(yàn)證成功,即可知道這個(gè)秘鑰是可以信任的秘鑰。
總結(jié)
Https的通信流程:

1、Client發(fā)起請求
2、Server端響應(yīng)請求,并在之后將證書發(fā)送至Client
3、Client使用認(rèn)證機(jī)構(gòu)的共鑰認(rèn)證證書,并從證書中取出Server端共鑰。
4、Client使用共鑰加密一個(gè)隨機(jī)秘鑰,并傳到Server
5、Server使用私鑰解密出隨機(jī)秘鑰
6、通信雙方使用隨機(jī)秘鑰最為對稱秘鑰進(jìn)行加密解密。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容