- 相關(guān)推薦
HTTP會(huì)話原理解釋與應(yīng)用
導(dǎo)語(yǔ):通過(guò)會(huì)話管理能夠?qū)?huì)話進(jìn)行創(chuàng)建、信息存儲(chǔ)、關(guān)閉。下面就由小編為大家介紹一下HTTP會(huì)話原理解釋與應(yīng)用,歡迎大家閱讀!
一、什么是會(huì)話
首先解釋一下什么是會(huì)話。在計(jì)算機(jī)術(shù)語(yǔ)中,會(huì)話是指一個(gè)終端用戶與交互系統(tǒng)進(jìn)行通訊的過(guò)程,比如從輸入賬戶密碼進(jìn)入操作系統(tǒng)到退出操作系統(tǒng)就是一個(gè)會(huì)話過(guò)程。會(huì)話較多用于網(wǎng)絡(luò)上,TCP的三次握手就創(chuàng)建了一個(gè)會(huì)話,TCP關(guān)閉連接就是關(guān)閉會(huì)話。用平述的語(yǔ)言可以解釋為:你拔打你女友的電話號(hào)碼,你女友接聽(tīng),然后一翻“親愛(ài)的”,直到任何一方掛掉電話,這個(gè)過(guò)程就是一個(gè)會(huì)話。你挑逗一只小狗,它跟你互動(dòng),也是會(huì)話;它不鳥(niǎo)你,那就不形成會(huì)話。
二、什么是HTTP會(huì)話
協(xié)議的狀態(tài)是指下一次傳輸可以“記住”這次傳輸信息的能力,HTTP是不會(huì)為了下一次連接而維護(hù)這次連接所傳輸?shù)男畔⒌摹膫鹘y(tǒng)WEB上看:無(wú)狀態(tài)是指,當(dāng)瀏覽器發(fā)送請(qǐng)求給服務(wù)器的時(shí)候,服務(wù)器響應(yīng),但是同一個(gè)瀏覽器再發(fā)送請(qǐng)求給服務(wù)器的時(shí)候,他會(huì)響應(yīng),但是他不知道你就是剛才那個(gè)瀏覽器,簡(jiǎn)單地說(shuō),就是服務(wù)器不會(huì)去記得你,所以是無(wú)狀態(tài)協(xié)議。本質(zhì)是:HTTP1.0是短連接的(這里先忽略HTTP1.1的keep alive吧),請(qǐng)求響應(yīng)后,斷開(kāi)了TCP連接,下一次連接與上一次無(wú)關(guān)。為了識(shí)別不同的請(qǐng)求是否來(lái)自同一客戶,引用HTTP會(huì)話機(jī)制,即:多次HTTP連接間維護(hù)用戶與同一用戶發(fā)出的不同請(qǐng)求之間關(guān)聯(lián)的情況稱為維護(hù)一個(gè)會(huì)話(session)。通過(guò)會(huì)話管理對(duì)會(huì)話進(jìn)行創(chuàng)建、信息存儲(chǔ)、關(guān)閉等。
三、HTTP會(huì)話的實(shí)現(xiàn)機(jī)制
Cookie與session是各種教材,網(wǎng)上文章所介紹到的與HTTP會(huì)話相關(guān)的兩個(gè)內(nèi)容。這種者較常見(jiàn)的解釋是:cookie存在在瀏覽器,session存儲(chǔ)在服務(wù)器中。這種解釋是最顯淺的,很不嚴(yán)謹(jǐn),但又不能說(shuō)是錯(cuò)誤。先從cookie談起吧,很久很久以前,為了完成HTTP會(huì)話,那些互聯(lián)網(wǎng)的設(shè)計(jì)者們想到了一個(gè)辦法,就是在瀏覽器中存儲(chǔ)用戶信息,每次請(qǐng)求都向服務(wù)端發(fā)送這些信息,這樣服務(wù)端就知道請(qǐng)求發(fā)送者是誰(shuí)了,就知道應(yīng)該返回什么信息給客戶了。但是問(wèn)題很快就出現(xiàn)了,張三冒充李四的名字發(fā)送請(qǐng)求給服務(wù)器,服務(wù)器把李四的相關(guān)信息發(fā)給了張三。為了安全起見(jiàn),互聯(lián)網(wǎng)老大哥們又想到了一招識(shí)別用戶身份的辦法,就是把客戶信息存儲(chǔ)在服務(wù)端(session),一切用戶的身份由服務(wù)器指定。直到目前,session已成功HTTP會(huì)話的主流,應(yīng)該說(shuō)是絕對(duì)控制的地位。
Session是怎樣做到會(huì)話身份識(shí)別的呢?首先,用戶端向服務(wù)端發(fā)送一個(gè)請(qǐng)求,服務(wù)端接收到請(qǐng)求(這里忽悠無(wú)須會(huì)話控制的情況)后,初始化會(huì)話,生成相應(yīng)的會(huì)話信息,核心是會(huì)話ID,把會(huì)話ID發(fā)送給客戶端,客戶端接收到這個(gè)會(huì)話ID,把它存儲(chǔ)起來(lái),下一次發(fā)送請(qǐng)求的時(shí)候,附帶著這個(gè)會(huì)話ID一起發(fā)送給服務(wù)端,服務(wù)端只要根據(jù)這個(gè)會(huì)話ID,就知道是誰(shuí)了。這個(gè)會(huì)話ID,就像我們的身份證號(hào)碼,一直伴隨終生。核心:服務(wù)端如何生成這個(gè)會(huì)話ID,客戶端怎樣存儲(chǔ)這個(gè)會(huì)話ID。
四、如何存儲(chǔ)會(huì)話ID(SESSION ID)
服務(wù)端存儲(chǔ)會(huì)話ID有多種方式,常見(jiàn)的有本地存儲(chǔ),如:普通文本,文本名就是會(huì)話ID。對(duì)于文件系統(tǒng),同一目錄下,同一文件名只允許唯一一個(gè)文件,那么使用會(huì)話ID作為文件名是可以做到唯一確定會(huì)話的。除了本地文件存儲(chǔ),還可以使用memcache、redis、或者M(jìn)ysql之類(lèi)的數(shù)據(jù)庫(kù)存儲(chǔ),即使用第三方數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)。只有一個(gè)原則:存儲(chǔ)的會(huì)話ID必須是唯一的。
客戶端收到服務(wù)端返回的(或者說(shuō)服務(wù)端下發(fā)的)會(huì)話ID后,也是像服務(wù)端那樣使用文件名作為會(huì)話ID存儲(chǔ)會(huì)話信息到文本嗎?如果客戶端只與同一個(gè)服務(wù)端(理解為同一個(gè)服務(wù)端處理程序)進(jìn)行會(huì)話通訊的話,是可行的。但是,HTTP是因萬(wàn)維網(wǎng)而生的,瀏覽器作為最常見(jiàn)的HTTP客戶端,需要訪問(wèn)各種不同的網(wǎng)站,如果采用會(huì)話ID作為文件名,以這樣的文件存在會(huì)話信息的話,會(huì)出現(xiàn)這樣的情況:N個(gè)不同的網(wǎng)站,服務(wù)端采用的是相同的會(huì)話生成算法,在同一時(shí)刻,很可能會(huì)生成一樣的會(huì)話ID,客戶端則無(wú)法唯一確定這個(gè)會(huì)話ID到底是與哪個(gè)服務(wù)端通訊,也就是客戶端“不認(rèn)得”服務(wù)端了,會(huì)話就無(wú)法完成。如何確定服務(wù)端身份?那就是使用“域”,不同的域擁有獨(dú)立的會(huì)話?蛻舳艘杂蛳嚓P(guān)信息作為文件標(biāo)識(shí)符創(chuàng)建會(huì)話文件(客戶端存儲(chǔ))對(duì)會(huì)話信息進(jìn)行存儲(chǔ),其中域與會(huì)話ID結(jié)合就能唯一確定服務(wù)端,并且確定會(huì)話。那么,以“域”信息作為文件名的文件中存儲(chǔ)著會(huì)話ID等信息。每次請(qǐng)求某個(gè)域的服務(wù)時(shí),把存儲(chǔ)著的會(huì)話ID附帶到請(qǐng)求中發(fā)送到服務(wù)端。瀏覽器是最常見(jiàn)的HTTP客戶端,瀏覽器存儲(chǔ)會(huì)話信息,是使用COOKIE文件的,里面保存著COOKIE信息,而服務(wù)端返回的會(huì)話ID也存儲(chǔ)在里面。會(huì)話ID存儲(chǔ)在COOKIE文件中是一般情況下的,而COOKIE信息是作為HTTP頭發(fā)送給服務(wù)端的,也就是說(shuō)這種情況下,會(huì)話ID是附帶在請(qǐng)求頭中。但是,HTTP請(qǐng)求,除了頭信息,還可以有內(nèi)容體,必須有URL。那么,會(huì)話ID同樣可以存儲(chǔ)在內(nèi)容體中或URL中,比如在禁用瀏覽器COOKIE的情況下,也可實(shí)現(xiàn)與服務(wù)端會(huì)話,要么依賴內(nèi)容體,要么依賴URL,常見(jiàn)的是URL中附帶會(huì)話ID,這個(gè)在PHP等編程語(yǔ)言中較為常見(jiàn)(曾經(jīng)的歷史上常見(jiàn),但是會(huì)涉及安全或者效率等問(wèn)題,這里不詳述)。
粗糙地,可理解為服務(wù)端返回給客戶端的會(huì)話ID是存儲(chǔ)在COOKIE文件中的。COOKIE文件是由瀏覽器管理的,當(dāng)然在自實(shí)現(xiàn)的客戶端中,可以通過(guò)編程手段實(shí)現(xiàn)COOKIE文件管理,即客戶端會(huì)話的管理。舉例:IOS開(kāi)發(fā)者,可以把HTTP返回的信息頭存儲(chǔ)到沙盒中進(jìn)行管理。PHP開(kāi)發(fā)客戶端時(shí),可以把信息頭寫(xiě)到文件中,或第三方服務(wù)中,或網(wǎng)絡(luò)存儲(chǔ)中等等。
五、會(huì)話管理(SESSION)
會(huì)話管理包括:會(huì)話創(chuàng)建、會(huì)話識(shí)別、會(huì)話信息操作、會(huì)話生命周期、會(huì)話關(guān)閉。
注意:這一節(jié)中的服務(wù)端會(huì)話都看作是開(kāi)啟的,無(wú)特別情況不再交待。
1、會(huì)話創(chuàng)建
客戶端發(fā)起不帶會(huì)話ID(SESSION ID)的HTTP請(qǐng)求,服務(wù)端認(rèn)為還沒(méi)產(chǎn)生會(huì)話,即創(chuàng)建會(huì)話,生成會(huì)話ID并且在服務(wù)器中存儲(chǔ)相關(guān)會(huì)話信息,并通知客戶端已開(kāi)啟會(huì)話。一般情況下,是在返回給客戶端的HTTP header中的COOKIE項(xiàng)中附帶上會(huì)話ID,形式為:會(huì)話標(biāo)記:會(huì)話ID。客戶端根據(jù)返回的信息頭,設(shè)置本地COOKIE值并存儲(chǔ)。
2、會(huì)話識(shí)別
會(huì)話ID是會(huì)話的唯一標(biāo)識(shí)符,一個(gè)會(huì)話ID只會(huì)對(duì)應(yīng)一個(gè)會(huì)話,就像身份證號(hào)碼只對(duì)應(yīng)一個(gè)人一樣。HTTP中,服務(wù)端是被動(dòng)接受請(qǐng)求的,會(huì)話識(shí)別也是被動(dòng)的(觸發(fā)式)。服務(wù)端不需要知道發(fā)送請(qǐng)求的到底是誰(shuí),只需要知道對(duì)方發(fā)送過(guò)來(lái)的會(huì)話ID,把客戶端傳過(guò)來(lái)的會(huì)話ID與服務(wù)端存儲(chǔ)的會(huì)話ID進(jìn)行匹配。找不到這個(gè)會(huì)話ID,就認(rèn)為這個(gè)會(huì)話是不存在的。
舉例:服務(wù)器有個(gè)會(huì)話ID是“21412545jladfjljljqwr”,映射的值是“名字:張三,性別:男”?蛻舳酥灰(qǐng)求中的會(huì)話ID是“21412545jladfjljljqwr”,就識(shí)別到這個(gè)會(huì)話了,能認(rèn)為這人是張三,而且是男性。如果客戶端請(qǐng)求的會(huì)話ID是“qwesadfasdfadsfasdf”,即使客戶端附帶了信息“名字:張三,性別:男”,服務(wù)端都認(rèn)為不存在此人,不形成會(huì)話。就算是李四盜用了張三的會(huì)話ID,服務(wù)端也會(huì)識(shí)別這個(gè)會(huì)話。
可簡(jiǎn)單理解為:SESSION只根據(jù)SESSION ID建立起會(huì)話,是不負(fù)責(zé)安全校驗(yàn)的,只負(fù)責(zé)讓服務(wù)端與客戶端可以“通話”。
3、會(huì)話信息操作
服務(wù)端:會(huì)話ID映射信息,ID不變,映射的內(nèi)容可變
客戶端:會(huì)話ID映射信息,ID不變,映射的內(nèi)容可變(即存在在COOKIEk中的內(nèi)容可變)。
服務(wù)端與客戶端的會(huì)話信息只有會(huì)話ID是必須相同的,其它會(huì)話信息(即會(huì)話ID映射的信息)沒(méi)有直接關(guān)系。
4、會(huì)話生命周期
會(huì)話從開(kāi)始到結(jié)束就是會(huì)話的生命周期。設(shè)定一個(gè)時(shí)間,這個(gè)時(shí)間內(nèi)無(wú)通訊就清除會(huì)話信息,我們就把這個(gè)時(shí)間叫做會(huì)話超時(shí)周期。
習(xí)慣地,我們把會(huì)話超時(shí)周期叫做會(huì)話的生命周期,其實(shí)這是兩個(gè)概念。
5、會(huì)話關(guān)閉
會(huì)話關(guān)閉,有2種方式。一種是用戶主動(dòng)清除會(huì)話信息,另一種是會(huì)話超時(shí)。會(huì)話超時(shí)不是守護(hù)任務(wù)(或自動(dòng)任務(wù))周期性檢查處理的,而是訪問(wèn)會(huì)話信息時(shí),根據(jù)會(huì)話信息中的“上一次更新時(shí)間”到現(xiàn)在的時(shí)間差,與會(huì)話周期比較,超出周期的,清除會(huì)話信息,即會(huì)話關(guān)閉。
經(jīng)典例子:會(huì)話過(guò)程中,突然斷網(wǎng)。
六、會(huì)話校驗(yàn)與HTTP協(xié)議冪等性
HTTP冪等性簡(jiǎn)述:
從定義上看,HTTP方法的冪等性是指一次和多次請(qǐng)求某一個(gè)資源應(yīng)該具有同樣的副作用。冪等性屬于語(yǔ)義范疇,正如編譯器只能幫助檢查語(yǔ)法錯(cuò)誤一樣,HTTP規(guī)范也沒(méi)有辦法通過(guò)消息格式等語(yǔ)法手段來(lái)定義它,這可能是它不太受到重視的原因之一。但實(shí)際上,冪等性是分布式系統(tǒng)設(shè)計(jì)中十分重要的概念,而HTTP的分布式本質(zhì)也決定了它在HTTP中具有重要地位。
舉個(gè)例子(摘抄網(wǎng)上):假設(shè)有一個(gè)從賬戶取錢(qián)的遠(yuǎn)程API(可以是HTTP的,也可以不是),我們暫時(shí)用類(lèi)函數(shù)的方式記為:bool withdraw(account_id, amount)。請(qǐng)求服務(wù)端,減小account_id的amount金額,成功返回true;失敗金額不變,返回false。
如果服務(wù)端成功了,并返回true,但網(wǎng)絡(luò)中斷,客戶端收不到信息,客戶端認(rèn)為取錢(qián)失敗,再次請(qǐng)求,服務(wù)端再一次扣費(fèi)。這里就涉及一個(gè)重復(fù)請(qǐng)求同一操作的問(wèn)題了。
要解決這個(gè)問(wèn)題,我們可以把withdraw設(shè)計(jì)為冪等的。create_ticket的語(yǔ)義是獲取一個(gè)服務(wù)器端生成的唯一的處理號(hào)ticket_id,它將用于標(biāo)識(shí)后續(xù)的操作。idempotent_withdraw和withdraw的區(qū)別在于關(guān)聯(lián)了一個(gè)ticket_id,一個(gè)ticket_id表示的操作至多只會(huì)被處理一次,每次調(diào)用都將返回第一次調(diào)用時(shí)的處理結(jié)果。這樣,idempotent_withdraw就符合冪等性了,客戶端就可以放心地多次調(diào)用。
從上面例子可以看到create_cicket的作用是生成ID識(shí)別碼,后續(xù)操作均基于此ID。會(huì)話ID本質(zhì)上也是冪等性的,生成ID后,后續(xù)操作均帶上ID參數(shù),即建立操作信息與ID的對(duì)應(yīng)關(guān)系。上面的例子并不是安全的,只是確保了操作對(duì)于同一個(gè)人(一次會(huì)話過(guò)程)是唯一的。同樣,會(huì)話ID只作為身份唯一的識(shí)別,不是安全的保證。
簡(jiǎn)單會(huì)話校驗(yàn):
一種較簡(jiǎn)單的會(huì)話校驗(yàn)是使用令牌,即請(qǐng)求中除了會(huì)話ID,至少還攜帶了令牌。服務(wù)端對(duì)令牌校驗(yàn)。令牌由服務(wù)端根據(jù)某種算法生成,令牌校驗(yàn)也在服務(wù)端中處理,客戶端只需存儲(chǔ)令牌,在請(qǐng)求中攜帶令牌,令牌生成算法的復(fù)雜程度影響令牌校驗(yàn)的安全性。
舉例:tokenFunc(param,value=’’) 第一個(gè)參數(shù)為令牌生成參數(shù),第二個(gè)參數(shù)為T(mén)oken值。當(dāng)?shù)诙䥇?shù)為空時(shí),成生Token,返回string;第二個(gè)參數(shù)不為空時(shí),檢查T(mén)oken準(zhǔn)確性 ,返回bool. 一般不需要解密,只要散列加密即可。PHP代碼如下:
function token($param,$value=’’){
if(!is_string($param){
$param = serialize($param);
}
$token = md5($param.’sault’);
if(!empty($value)){
if($value == $token){
return true;
}else{
return false;
}
}else{
return $token;
}
}
生成令牌:$token = token($session_id);
檢驗(yàn)令牌:$check = token($session_id,$token);
七、會(huì)話原理的應(yīng)用
瀏覽器默認(rèn)是開(kāi)啟Cookie的,瀏覽器發(fā)起HTTP請(qǐng)求時(shí),在請(qǐng)求頭中帶有Cookie信息,只要服務(wù)端返回Cookie中包含SessionID,在服務(wù)端根據(jù)Sessionid即實(shí)現(xiàn)HTTP會(huì)話,此過(guò)程對(duì)于前端開(kāi)發(fā)者是透明的(即前端開(kāi)發(fā)可以不關(guān)心瀏覽器是怎樣與服務(wù)端確定會(huì)話的)。
除即時(shí)通訊,實(shí)時(shí)動(dòng)作網(wǎng)游外,大多APP是使用HTTP協(xié)議與服務(wù)端通訊的,使用HTTP協(xié)議的原因主要是移動(dòng)網(wǎng)絡(luò)環(huán)境復(fù)雜(容易斷線),并且HTTP協(xié)議穿透性強(qiáng)。原生開(kāi)發(fā)的IOS,安卓等APP,與服務(wù)端會(huì)話,可不使用COOKIE,只需要在請(qǐng)求中攜帶會(huì)話ID即可,這在上文已描述。原生APP與內(nèi)嵌瀏覽器的APP相比:原生實(shí)現(xiàn)性能更高,交互效果流暢,用戶體驗(yàn)相對(duì)較好,但快速跌代比不上內(nèi)嵌瀏覽器的APP。手機(jī)配置越來(lái)越高,內(nèi)嵌瀏覽器對(duì)HTML5支持也越來(lái)越好,在性能要求不是很高的場(chǎng)景,內(nèi)嵌WEB的性能已可滿足,在布局多變,或者元素多變的情況下,可快速修改,而無(wú)需用戶升級(jí)APP,也能獲得更好的產(chǎn)品體驗(yàn)。APP內(nèi)嵌WEB最常見(jiàn)的場(chǎng)景就是電商APP了,登陸、注冊(cè)、入口等交互效果較多的模塊使用原生程序開(kāi)發(fā),而商品列表、商品展示等等模塊可采用內(nèi)嵌WEB,這樣既可滿足快速產(chǎn)品跌代的要求,又可滿足操作的性能要求。
舉例:電商APP入門(mén)界面、登陸、注冊(cè)是使用原生開(kāi)發(fā)的,登陸后跳轉(zhuǎn)到商品列表頁(yè)(即內(nèi)嵌WEB),然后下訂單。問(wèn)題來(lái)了,如何使得登陸后跳轉(zhuǎn)到WEB后,還是登陸狀態(tài)(即內(nèi)嵌WEB與原生程序具有一致的會(huì)話)呢?內(nèi)嵌WEB是不會(huì)去取得原生程序所存儲(chǔ)的data的。最簡(jiǎn)單直接的辦法就是:登陸成功,服務(wù)器返回會(huì)話ID與成功信息,跳轉(zhuǎn)到WEB時(shí),發(fā)送的HTTP請(qǐng)求頭中包括COOKIE,會(huì)話ID存儲(chǔ)在COOKIE中,這樣之后點(diǎn)擊WEB中的鏈接后向服務(wù)端發(fā)送的HTTP請(qǐng)求頭,就會(huì)攜帶這個(gè)COOKIE(會(huì)話ID)了。簡(jiǎn)單地理解:終端原生程序請(qǐng)求服務(wù)端,服務(wù)端按普通WEB那樣返回信息,終端原生程序取得HTTP返回頭中的COOKIE信息,保存下來(lái),下一次請(qǐng)求時(shí),攜帶COOKIE信息即可。在瀏覽器中,COOKIE的處理由瀏覽器默認(rèn)處理,而在原生APP程序中,由開(kāi)發(fā)者寫(xiě)程序去處理而已。
【HTTP會(huì)話原理解釋與應(yīng)用】相關(guān)文章:
網(wǎng)頁(yè)設(shè)計(jì)中的數(shù)學(xué)原理應(yīng)用03-05
計(jì)算機(jī)原理中C語(yǔ)言的應(yīng)用01-02
關(guān)于計(jì)算機(jī)原理中C語(yǔ)言的應(yīng)用06-02
PHP實(shí)現(xiàn)HTTP斷點(diǎn)續(xù)傳的方法07-10