【面試高頻】cookie、session、token?看完再也不擔心被問了

在以往的面試記錄裏,我又看到了一個多次被問到的知識點,那就是 cookie、session、token 的區別有哪些?如果現在來問你,不知道你能否說清楚呢?

今天不僅僅是整理出這三者的區別,更重要的是能夠真正去理解這三者之間的作用和聯繫。

cookie、session、token三者聯繫

在互聯網裏,一樣事物的誕生往往是爲了解決某種問題,這句話同樣適用於此。

其實說到底,cookie、session、token 都圍繞了一個點:身份認證

爲什麼要認證

很簡單,比如電商購物網站需要登錄。在輸入賬號密碼點擊登錄之後,對服務器就產生了一次會話 session,就像你我之間進行了一次交談,我根據你的名字樣貌記住了你。那麼服務器也需要能夠記住你,需要把大家區分開來。

但是,由於http協議是無狀態的,已經登錄過的用戶沒法通過協議層把狀態保存下來,所以下次再請求的時候,服務器還是不知道你是誰。

有什麼辦法呢?

Session

當服務器收到登錄請求之後,生成一個 session id 一起返回給客戶端,客戶端下次再請求的時候把 session id 一起帶上。這時候每個客戶端請求對應各自的 session id
,服務就知道怎麼區分了。

而客戶端與服務器之間的會話,一般會使用 Cookie 來管理。

服務在向客戶端返回響應時,會在首部字段Set-Cookie內寫入 Session ID(如 PHPSESSID=028a8c…)。

客戶端接收到從服務器端發來的 Session ID 後,會將其作爲 Cookie 保存在本地。

比如我登錄了一個論壇,瀏覽器 F12 就可以看到保存在本地的 cookie。

產生的問題

由於服務器也要保存這 session信息用於跟客戶端傳過來的進行比對,數量小了還好,請數量大了,服務器要保存的內容頁就越多,會喫不消。

此外,還會影響服務器的拓展能力。比如服務由2臺機器組成一個集羣,而我之前登錄後,session id保存在服務器A上,但是下次請求如果發送到服務器B就不行了,因爲人家沒存,所以不認。

還會有如下等問題:

  • 對於非瀏覽器的客戶端、手機移動端等不適用,因爲session依賴於cookie,而移動端經常沒有cookie
  • 因爲session認證本質基於cookie,所以如果cookie被截獲,用戶很容易收到跨站請求僞造攻擊。並且如果瀏覽器禁用了cookie,這種方式也會失效
  • 前後端分離系統中更加不適用,後端部署複雜,前端發送的請求往往經過多箇中間件到達後端,cookie中關於session的信息會轉發多次
  • 由於基於Cookie,而cookie無法跨域,所以session的認證也無法跨域,對單點登錄不適用

服務器:唉!該死的 sessionid,要是可以不用該多好呀 o(╥﹏╥)o。

Token

嗯?其實這個事情核心在於身份認證,想個辦法既能解決認證,又不用服務器保存不就好了:

  1. 客戶端使用用戶名和密碼請求登錄
  2. 服務端收到請求,驗證用戶名和密碼
  3. 驗證成功後,服務端會簽發一個 token 令牌,再把這個token返回給客戶端
  4. 客戶端收到 token 後可以把它存儲起來,比如放到cookie中
  5. 客戶端每次向服務端請求資源時需要攜帶服務端簽發的 token,可以在 cookie 或者 header 中攜帶
  6. 服務端收到請求,然後去驗證客戶端請求裏面帶着的 token,如果驗證成功,就向客戶端返回請求數據

重點就是在於服務端可以不用保存 token。

比如,當第一次收到客戶端傳過來的用戶名和密碼時,服務器認證通過後,通過加密算法生成一個字符串當做 token。當拿到後續請求中的 token,服務器再解析這個token,可以從中獲取關鍵的信息,從而判斷該token的有效性。

目前接觸到的大多數系統,都是基於token驗證來的,因爲它的優點更適合當下的系統應用環境:

  • 無狀態,可以更方便擴展
  • 更安全,可以防止跨站請求僞造 CSRF
  • 方便多平臺跨域
  • 可以標準化,比如基於JWT Json web token (JWT)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章