Cookie,Session,Token

我們知道HTTP是一種無狀態的協議,爲了分辨鏈接是誰發起的,需自己去解決這個問題。而且一旦數據交換完畢,客戶端與服務器端的連接就會關閉,再次交換數據需要建立新的連接。這就意味着服務器無法從連接上跟蹤會話。導致有些情況下即使是同一個網站每打開一個頁面也都要登錄一下。而SessionCookie就是爲解決這個問題而提出來的兩個機制。

同樣的Token也能解決這個問題,它們之間只是一個說法的差別,其實做的事情都是一樣的。

Cookie

實際上是一小段的文本信息是訪問某些網站後在本地存儲的一些網站相關信息,下次訪問時減少一些步驟。更準確的說法是:Cookie是服務器在本地機器上存儲的小段文本信息並隨每一個請求發送至同一服務器,是在客戶端保持狀態的方案。主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成Cookie的作用範圍。

會話Cookie和持久Cookie

若不設置過期時間,則表示這個 cookie 的生命期爲瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期爲瀏覽器會話期的cookie被稱爲會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存裏,當然這種行爲並不是規範規定的。若設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以在瀏覽器的不同進程間共享。這種稱爲持久Cookie

Session

它存在服務器的一種用來存放用戶數據的類HashTable結構,是另一種記錄客戶狀態的機制,不同的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是Session。客戶端瀏覽器再次訪問時只需要從該Session中查找該客戶的狀態就可以了。

session的創建

當程序需要爲某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求裏是否已包含了sessionId,如果已包含則說明以前已經爲此客戶端創建過session,服務器就按照sessionId把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含sessionId,則爲此客戶端創建一個session並且生成一個與此session相關聯的sessionIdsessionId的值是一個既不會重複,又不容易被找到規律以仿造的字符串,這個sessionId將被在本次響應中返回給客戶端保存。

當服務器爲用戶建立一次會話,可以在用戶授權成功時給他一個唯一的cookie。當一個用戶提交了表單時,瀏覽器會將用戶的SessionId自動附加在HTTP頭信息中,服務器通過SessionId作爲key,讀寫到對應的value,這就達到了保持會話信息的目的。

如果客戶端禁用了cookie,通常有兩種方法實現session而不依賴cookieURL重寫,就是把sessionId直接附加在URL路徑的後面;表單隱藏字段。

Session共享

對於多網站(同一父域不同子域)單服務器,我們需要解決的就是來自不同網站之間SessionId的共享。由於域名不同(aaa.test.combbb.test.com),而SessionId又分別儲存在各自的cookie中,因此服務器會認爲對於兩個子站的訪問,是來自不同的會話。解決的方法是通過修改cookies的域名爲父域名達到cookie共享的目的,從而實現SessionId的共享。帶來的弊端就是,子站間的cookie信息也同時被共享了。

Cookie和Session的區別

  • CookieSession都是會話技術,Cookie是運行在客戶端,Session是運行在服務器端。
  • Cookie有大小限制以及瀏覽器在存cookie的個數也有限制(單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie),Session是沒有大小限制和服務器的內存大小有關。
  • Cookie有安全隱患,通過攔截或本地文件找得到你的cookie後可以進行攻擊。
  • Session是保存在服務器端上會存在一段時間纔會消失,如果session過多會增加服務器的壓力。

Session的弊端以及Token的引入

弊端:

  • 服務器壓力增大:通常 session 是存儲在內存中的,每個用戶通過認證之後都會將 session 數據保存在服務器的內存中,而當用戶量增大時,服務器的壓力增大。

  • CSRF 跨站僞造請求攻擊:session 是基於 cookie 進行用戶識別的, cookie 如果被截獲,用戶就會很容易受到跨站請求僞造的攻擊。

  • 擴展性不強

 

token一般組成(token組成:uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign(簽名,由token的前幾位+鹽以哈希算法壓縮成一定長的十六進制字符串,可以防止惡意第三方拼接token請求服務器)。還可以把不變的參數也放進token,避免多次查庫)

token,註冊登錄 -> 服務端將生成一個 token,並將 token 與 user 加密生成一個密文 -> 將 token + user + 密文數據 返回給瀏覽器 -> 再次訪問時傳遞 token + user + 密文數據,後臺會再次使用 token + user,生成新密文,與傳遞過來的密文比較,一致則正確。就是 token 從設計上必須通過 get 參數或者 post 參數提交,一般是不允許保存在cookies 當中的,容易產生 CSRF 漏洞。

token 與 session 的不同主要在①認證成功後,會對當前用戶數據進行加密,生成一個加密字符串 token,返還給客戶端(服務器端並不進行保存)

②瀏覽器會將接收到的 token 值存儲在 Local Storage 中,(通過 js 代碼寫入 Local Storage,通過 js 獲取,並不會像 cookie 一樣自動攜帶)

③再次訪問時服務器端對 token 值的處理:服務器對瀏覽器傳來的 token 值進行解密,解密完成後進行用戶數據的查詢,如果查詢成功,則通過認證,實現狀態保持,所以,即時有了多臺服務器,服務器也只是做了 token 的解密和用戶數據的查詢,它不需要在服務端去保留用戶的認證信息或者會話信息,這就意味着基於 token 認證機制的應用不需要去考慮用戶在哪一臺服務器登錄了,這就爲應用的擴展提供了便利,解決了 session 擴展性的弊端。

Cookie 和 Token 的區別

token 和 cookie 一樣都是首次登陸時,由服務器下發,都是當交互時進行驗證的功能,作用都是爲無狀態的 HTTP 提供的持久機制。

token存在哪兒都行,localstorage (在 HTML5 中,新加入了一個 localStorage 特性,這個特性主要是用來作爲本地存儲來使用的,解決了 cookie 存儲空間不足的問題)或者 cookie。

對於 token 而言,服務器不需要去查看你是誰,不需要保存你的會話。當用戶 logout 的時候 cookie 和服務器的session 都會註銷;但是當 logout 時候 token 只是註銷瀏覽器信息,不查庫。

token 優勢在於,token 由於服務器端不存儲會話,所以可擴展性強,token 還可用於 APP 中。(可以避免 CSRF 攻擊,可以是無狀態的,可以在多個服務間共享)。

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