狀態保持的常用手法,原理,以及優劣

狀態保持的常用手法,原理,以及優劣

首先解釋問什麼要進行狀態保持:
    直接原因:
        http協議是一個無狀態的協議: http協議通過socket(套接字)進行通信,客戶端連接服務器,一次數據傳輸完成之後,
        客戶端會斷開於服務器的連接,服務器也會銷燬前一次的連接對象,因此,http協議是一個不能保持狀態(無狀態)的協議
        
    需求:
        我們的Web服務器總是希望能夠讓服務端和客戶端彼此認識(保持當前的狀態), 從而不至於讓用戶每跳轉一個頁面就登陸一次,造成極差的用戶體驗
        
手段一: Cookie
    特點
        cookie是保存在客戶端的一個文本文件,一般大小單個文件大小不會超過4kb,只能存非中文和字符串類型,不能存儲對象,根據操作系統和瀏覽器的不同,存儲的位置也不盡相同,大體上存放在硬盤或內存中
    流程:    
        當瀏覽器向服務器發送請求後,服務器會給客戶端發送一些響應信息,其中有一部分會保存在由服務器生成的文本文件(cookie)中,
        保存的信息可以是用戶名,id, 瀏覽記錄,歷史記錄,如果你在登錄的時候選擇了保存密碼,那還會保存你的密碼信息(之前有網站就這麼幹,後來連官網都被黑掉了)
        如果下一次瀏覽器再一次請求服務器, 就瀏覽器會在cookie中查找這臺服務器域名下的相關信息, 附在請求中,一併發給服務器,服務器就可以解析cookie的信息,然後獲知用戶的身份,權限等一系列用戶信息了
        
    優缺點:
        這麼做優勢很明顯,即即可以實現狀態保持,又不消耗服務器的任何存儲資源(cookie存客戶端了嘛), 唯一增加的是在請求時多攜帶了一些數據而已,這些數據小到簡直可以忽略不計
        缺點也很明顯: 由於cookie存儲在本地,就相當於把網站的很多信息暴露給了有心之人,即使你的cookie信息加了密,那些有心之人也有辦法解密,不然你覺得上面的那個網站的官網是怎麼被黑掉的, 採用cookie的狀態保持手段安全性相對較低
    
手段二: session
    特點:
        session是基於cookie的, session存儲的容量大,可以存儲對象,ession存儲在服務器端,一般是內存中,或數據庫中
    流程:
        當瀏覽器向服務器發送請求後,服務器在響應客戶端的同時,會在服務器內部保存這個用戶的所有登錄信息,並存儲起來,並根據這個用戶的全部信息生成一個針對於這個用戶的sessiondi,
        來唯一標識這個用戶的所有信息,以形成一種一一對應關係(類似於python中的字典,一鍵一值的形式), 並把生成的唯一表示sessionid也響應給瀏覽器,瀏覽器接收到響應之後,會將sessionid存儲在cookie中
        下一次該用戶在請求這臺服務器時,瀏覽器就會把這臺服務器下的域名所對應的sessiondi連同請求一併發給服務器,服務器通過sessionid查找到這個用戶,並獲取用戶的相關信息,如果服務器沒有獲取到sessionid,就說明這個用戶並沒有在該網站中註冊
        保存用戶數據,生成sessionid,並返回就行了,
        但是也會遇到一些問題,如果在瀏覽器端,cookie被禁用掉了,那必須得有其他的機制來確保sessionid能夠準確無誤的傳回服務器,一般常用的方式是重寫url, 這裏也分爲兩種方式:
        一種就是sessionid當做url的附加信息進行傳遞如http://www.helloword.com/index;sessiondi=83re345#$@@_)*+HJTFV,
        另外一種就是把sessionid當做url的查詢參數傳遞如: http://www.helloword.com/index?sessiondi=83re345#$@@_)*+HJTFV,
        而另一種機制是表單隱藏字段:如果服務器發現客戶端禁用掉了cookie,那麼服務端就會修改表單,在表單中添加一個隱藏的字段,以保存sessionid,並保證在下一次的請求中,sessionid能被回傳給服務器
    優缺點:
        優點是:安全性提高了,你的用戶數據存放在服務器,一般不會被人黑掉,大大提高了數據的安全性
        缺點是:服務器的存儲資源那是相當的寶貴啊,前期用戶量少還好說,用戶量大了像Facebook,youtube,如果真的使用session的狀態保持手段,服務器會被撐爆炸的,太佔用服務器存儲資源了
        
手段三: jwt
    特點:
        jwt本身是json類型, 由於json的通用性,jwt也是通用的,跨語言特性很好, jwt本質上是一串字符串,比較小巧,一般存放在客戶端
    構成:
        1, 頭部(Header) 頭部是json形式,一般存放的是加密的方式和jwt的類型,
        2, 載荷(Playload) 載荷是json形式,存放的是一些基本信息, 如過期時間,要發給誰,簽發者是誰,簽發時間是多少
        3, 簽證(signature) 簽證的構成稍有複雜,將頭部和載荷使用base64加密過後,同過.進行連接,並且使用header中的加密方式進行secret加鹽加密,最後才得出簽證的值
        4, 整個jwt看起來像是這樣: eyJhbGciOiJI.eyJzdWIiOydWV9.TJVA95OrM7E2cB
        
    流程:
        當瀏覽器向服務器發送請求後,服務器在響應客戶端的同時,會在服務器內部把用戶的一些不敏感信息放入在jwt的載荷中,如id, name等,生成jwt,並將jwt一併響應給客戶端,客戶端接收到這個jwt之後,會存放在本地,
        以後每一次請求都會攜帶這個jwt,以便於保存用戶的登錄狀態,如果用戶需要登出,則把客戶端的jwt刪除即可,
        由於頭部和載荷都是採用base64進行的加密,理所應當也可以進行解密,因此頭部和載荷是不安全的,而由於簽證是由加鹽算法進行加密的,因此不能被篡改, 而一旦有人篡改了頭部或者載荷,在服務器收到請求之後,
        服務器會把收到的載荷和頭部採用相同的secret進行加鹽加密,得到新的簽證,如果跟老的簽證不一致,則說明信息被篡改了,直接返回瀏覽器錯誤信息即可.
        
總結:
        session和cookie相比,其實是拿存儲空間換取數據安全
        jwt和session,cookie相比,是以計算力(頻繁的加解密)換取存儲空間
       

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