? ? ? ?首先什么是session吊圾,字面意思是會(huì)話控制挥等。個(gè)人理解就是就是一套可以識(shí)別用戶的系統(tǒng)蝶念,為什么需要一套叫做session的東西來識(shí)別用戶呢抛腕?這就得從http協(xié)議說起,http協(xié)議是基于TCP/IP協(xié)議的一層封裝(為了讓大家都容易理解一些媒殉,我都以直白的方式來說担敌,盡量不扯太底層的東西)。用戶在訪問一個(gè)網(wǎng)站的時(shí)候廷蓉,每一次請(qǐng)求頁面之后都是斷開連接的全封,既然是斷開連接的马昙,那么我下一次訪問的時(shí)候服務(wù)器哥怎么知道是我再一次訪問呢?最簡(jiǎn)單的方式刹悴,第一次我給一個(gè)憑證你行楞,這個(gè)憑證記錄著一些與身份相關(guān)的信息,第二次你訪問的時(shí)候給我看這個(gè)憑證土匀,我就知道你是之前的那個(gè)用戶了子房。
憑證的交付
? ? ? ?既然我們知道用`憑證`這一個(gè)辦法可以識(shí)別用戶,那么好了就轧,我們就要想辦法給用戶一個(gè)憑證证杭。怎么給也是一個(gè)技術(shù)活,一個(gè)最簡(jiǎn)單的辦法:把憑證信息都放在cookie就行了妒御,反正用戶每次訪問都會(huì)帶著cookie訪問的解愤。
制作憑證
? ? ? ? 既然知道如何給用戶憑證了,那么服務(wù)器哥就很開心啦(可以識(shí)別用戶咯)乎莉,趕緊就開始制作憑證送讲,一開始就直接把用戶信息直接放到cookie里面(姓名:小明,性別:男惋啃,年齡不詳)李茫,這個(gè)時(shí)候把憑證給了小明,然后每一次小明都拿這個(gè)憑證給服務(wù)器哥看肥橙,然后就可以愉快的玩耍咯秸侣。
憑證的信任危機(jī)
? ? ? ? 一開始服務(wù)器哥非常相信用戶存筏,沒想到有一天,某個(gè)用戶竟然在憑證上偽造了內(nèi)容味榛,讓服務(wù)器哥誤認(rèn)為他是某個(gè)用戶(這個(gè)時(shí)候憑證是明文椭坚,該起來非常方便),然后被偽造的那個(gè)用戶的信息泄漏了搏色。善茎。。信息無價(jià)吶频轿,服務(wù)器哥怎么可能讓這事情蔓延下去垂涯,所以服務(wù)器哥立馬把憑證內(nèi)容加密了(這個(gè)加密是可逆加密),這個(gè)時(shí)候用戶拿到的是一堆看不懂的數(shù)據(jù)航邢,不過服務(wù)器哥自己可以解密耕赘,用戶也無法偽造憑證,這樣子就解決了一下憑證的信任危機(jī)膳殷。(python的flask框架就是這樣子處理的)
憑證內(nèi)容保密問題
? ? ? ?雖然服務(wù)器哥加密了憑證的內(nèi)容操骡,然而畢竟是可以解密的,假如有一些信息不希望用戶看到的,但是為了方便又想寫在憑證上面怎么辦呢册招。這個(gè)時(shí)候岔激,服務(wù)器哥想到給用戶的憑證只記錄一個(gè)唯一的編碼,然后在自己這里放著用戶憑證的具體數(shù)據(jù)是掰,然后為這個(gè)數(shù)據(jù)關(guān)聯(lián)編碼就好了虑鼎。
憑證保存問題
? ? ? ? ?既然憑證信息放在服務(wù)器哥這里,那么又該怎么存放呢冀惭。服務(wù)器哥想了幾套解決方案出來:
(1)基于文件的存儲(chǔ)
(2)基于數(shù)據(jù)庫的存儲(chǔ)
(3)基于內(nèi)存的存儲(chǔ)
(4)基于memcached的存儲(chǔ)
(5)基于redis的存儲(chǔ)
? ? ? ?基于文件的存儲(chǔ)震叙,我們只需要簡(jiǎn)單的以用戶拿到的唯一編碼作為文件名就好,具體信息放在文件里面(我之前寫的paas系統(tǒng)就是用了這種方案:https://github.com/yubang/app/blob/master/middle/session.py)散休。這種方案有幾個(gè)缺點(diǎn)媒楼,首先磁盤讀寫速度并不快,然后憑證的唯一編碼有過期時(shí)間戚丸,隨著時(shí)間的流失划址,廢棄的文件也會(huì)越來越多,所以還要定時(shí)刪除過期的文件限府。并且在多臺(tái)服務(wù)器的時(shí)候夺颤,還要保持每臺(tái)服務(wù)器都能讀取到這些文件。
? ? ? ?基于數(shù)據(jù)庫的存儲(chǔ)胁勺,這種方案跟基于文件差不多世澜,比文件的優(yōu)點(diǎn)是有多臺(tái)服務(wù)器的時(shí)候,只要連著一臺(tái)數(shù)據(jù)庫就可以保證讀取到這些數(shù)據(jù)署穗。
? ? ? ?基于內(nèi)存的存儲(chǔ)這方案主要優(yōu)點(diǎn)是讀寫數(shù)據(jù)比較快寥裂,然而內(nèi)存斷電后數(shù)據(jù)都沒了,并且程序之間內(nèi)存獨(dú)立了(不過linux系統(tǒng)有一個(gè)/dev/shm的目錄是映射到內(nèi)存的)案疲,并且多服務(wù)器時(shí)候讀取數(shù)據(jù)也是一個(gè)問題封恰,過期數(shù)據(jù)也要手動(dòng)清除。
? ? ? ?基于memcached這種方案其實(shí)跟內(nèi)存差不多褐啡,然而memcached幫我們解決了除了斷電數(shù)據(jù)丟失之外的大部分問題诺舔,在數(shù)據(jù)超過一定量時(shí)候刪除一些數(shù)據(jù),支持多臺(tái)服務(wù)器來讀取數(shù)據(jù)备畦。
? ? ? ? 基于redis這種方案其實(shí)是擁有了memcached的優(yōu)點(diǎn)低飒,并且斷電后數(shù)據(jù)還保存數(shù)據(jù)(哈哈,服務(wù)器哥再也不擔(dān)心斷電咯)
憑證交付難題
? ? ? ? 技術(shù)路總是困難重重的萍恕,服務(wù)器哥好不容易依靠cookie交付憑證逸嘀,解決了各種安全問題。突然有一天允粤,一個(gè)用戶說我不使用cookie的(服務(wù)器哥哭暈了)崭倘,用戶又不能得罪的翼岁,怎么辦呢?左想右想(技術(shù)總有替代方案的)司光,終于找到幾個(gè)辦法:
(1)每次請(qǐng)求都在url附帶上唯一編碼(哈哈琅坡,好辦法)【類似于我們平時(shí)調(diào)用第三方API】
(2)每次訪問在headers附帶上唯一編碼(也是辦法)
故事結(jié)局
? ? ? ?不知不覺這個(gè)故事就說完了,最后就是服務(wù)器哥利用一張憑證成功記住了用戶残家。
? ? ? ?總的來說榆俺,session就是給每一個(gè)用戶一個(gè)隨機(jī)的唯一的編號(hào),交付途徑可以是cookie坞淮,url或者h(yuǎn)eaders茴晋。而通過這個(gè)唯一的編碼,映射到服務(wù)器存儲(chǔ)的具體信息回窘,保存方案各種各樣有磁盤有內(nèi)存诺擅。
題外話
技術(shù)是無味的,代碼只是一堆字符啡直,然而代碼制作的產(chǎn)品卻是令人振奮的烁涌,我只想以最簡(jiǎn)單有趣的話解說最無味的底層技術(shù),如果喜歡的話酒觅,點(diǎn)贊是對(duì)我最好的支持撮执。