京東面試:說說Cookie、Session和Token的差別?

2023.12.08

京東面試:說說Cookie、Session和Token的差別?

Cookie、Session 和Token 通常都是用來保存使用者登入資訊的技術,但三者的差異很大:Cookie 適用於簡單的狀態管理,Session 適用於需要保護使用者敏感資訊的場景,而Token 適用於狀態無關的身份驗證和授權。

東子作為目前傳統電商三巨頭之一(其他還有阿里巴巴和拼多多),其面試題的難度也中規中矩,總體來說沒有其他兩家面試難度高,當然薪資也沒有其他兩家薪資高。

其中拼多多的薪資最為離譜,尤其是前幾年,聽說挖同行的開發人員,薪資可以開到原來薪資的兩到三倍,真是變態(但是我喜歡)。

東子的面試題目如下:

圖片圖片

其中大部分面試題目可以在我的網站上找到答案(www.javacn.site),這裡就不再贅述了。咱們今天只聊:Cookie、Session 和Token 的差別?

1.Cookie、Session 和Token 有什麼不同?

Cookie、Session 和Token 通常都是用來保存使用者登入資訊的技術,但三者有很大的區別,簡單來說Cookie 適用於簡單的狀態管理,Session 適用於需要保護使用者敏感資訊的場景,而Token適用於狀態無關的身份驗證和授權。

Token 狀態無關性解析:在傳統的基於會話的認證方式中,伺服器需要在後端保存使用者的會話狀態,透過Session ID 進行會話的管理。而Token 機制不需要在伺服器上保存任何關於使用者的狀態訊息,只需要在登入成功時,伺服器端透過某種演算法產生一個唯一的Token 值,之後再將此Token 傳送給客戶端儲存(儲存在localStorage或sessionStorage 中),注意此時服務端是不儲存這個Token 值的,伺服器端只進行效驗而不保存此Token,這就叫「狀態無關性」。這樣就可以減輕伺服器儲存和管理會話狀態的負擔,所以它比較適用於大型系統和分散式系統。

具體來說,Cookie、Session 和Token 的差異主要有以下幾點差異:

  1. 儲存位置不同:Cookie 儲存在客戶端,即瀏覽器中的文字文件,透過在HTTP 頭中傳遞給伺服器來進行通訊;Session 是伺服器端的儲存方式,通常儲存在伺服器的記憶體或資料庫中;Token 也是儲存在客戶端,但通常以加密的方式儲存在客戶端的localStorage 或sessionStorage 中。
  2. 資料安全性不同:Cookie 儲存在客戶端,可能會被竊取或篡改,因此對敏感資訊的儲存需要進行加密處理;Session 儲存在伺服器端,透過一個Session ID 在客戶端和伺服器之間進行關聯,可以避免敏感資料直接暴露;Token 通常使用加密演算法生成,有效期較短且單向不可逆,可以提供較高的安全性。
  3. 跨域支援不同:為了防止安全事故,因此Cookie 是不支援跨域傳輸的,也就是不同網域下的Cookie 是不能相互存取的;而Session 機制通常是透過Cookie 來保存Session ID 的,因此Session ID 預設情況下也是不支援跨域的;但Token 可以輕鬆實現跨域,因為Token 是儲存在客戶端的localStorage 或作為請求頭的一部分發送到伺服器的,所以不同的網域Token 資訊傳輸通常是不受影響的。
  4. 狀態管理不同:Cookie 是應用程式透過在客戶端儲存臨時數據,用於實現狀態管理的一種機制;Session 是伺服器端記錄使用者狀態的方式,伺服器會為每個會話分配一個唯一的Session ID,並將其與使用者狀態相關聯;Token 是一種用於認證和授權的一種機制,通常表示使用者的身份資訊和權限資訊。

2.Cookie 和Session 有什麼關係?

要精確來說 Cookie 的實作和Session 是沒有任何關係的,但Session 的實作需要藉助於Cookie。

Session 機制的實作流程如下:

  1. 會話建立:通常情況下,當使用者登入成功後,伺服器會為該使用者建立新的會話。在建立會話過程中,伺服器會為該會話產生一個唯一的標識符,通常稱為Session ID。
  2. Session ID 傳遞:伺服器將產生的Session ID 透過回應的方式傳送給客戶端,使用SetCookie 指令,將使用者的Session ID 保存在Cookie 中,通常是一個名為JSESSIONID 的Cookie。
  3. Session 資料儲存:在伺服器端,Session 資料會被儲存在一個能夠關聯Session ID 的資料結構中(例如記憶體、資料庫或檔案儲存等)。常用的方式是將Session ID 作為鍵,與對應的Session 使用者身分資料進行關聯。
  4. Session ID 驗證與檢索:當使用者傳送新的請求時,用戶端會將先前儲存的Session ID 攜帶在請求的Cookie 或請求頭中傳送給伺服器。伺服器會根據Session ID 找到對應的Session 數據,從而獲得使用者的狀態資訊。
  5. Session 資料使用:伺服器在取得Session 資料後,可以根據特定需求讀取、修改或刪除其中所儲存的狀態資訊。伺服器可以透過Session 來管理使用者的登入狀態、購物車內容、使用者配置等。
  6. Session 過期與銷毀:Session 有一個有效期限,一般透過設定一個固定的時間,或在一定時間內沒有使用者活動時會將Session 標記為過期。當Session 過期時,伺服器會銷毀對應的Session 數據,釋放記憶體或其他資源。

所以預設情況下,Session 是藉助Cookie 來完成身份標識的傳遞的,這樣伺服器端才能根據Session ID 和保存的會話資訊進行關聯,用於找到某個具體登入的用戶,所以說:預設情況下,Session機制是依賴Cookie 實現的。

3.禁用Cookie 之後Session 還能用嗎?

透過上文我們知道,預設情況下Session 機制是依賴Cookie 實現的,那麼是不是禁用了Cookie 之後,Session 機制也就無法使用了呢?其實不然。

除了預設情況下,我們可以使用Cookie 來傳遞Session ID 之外,我們可以透過一些特殊的手段來自行傳遞Session ID,以此來擺脫禁用Cookie 之後Session 無法使用的情況,例如以下兩種實作手段:

  1. URL Rewriting:可以在每個請求的URL 中附加Session ID 參數。伺服器在接收到請求時,解析URL 中的Session ID,並與對應的Session 資料進行關聯。這種方式適用於沒有停用網址列中的參數傳遞的情況。
  2. 隱藏表單欄位:可以將Session ID 作為隱藏表單欄位的方式傳遞給伺服器。當使用者提交表單時,Session ID 將隨著表單資料一起傳送給伺服器,伺服器據此建立與目前會話的關聯。

透過以上手段都可以將Session ID 傳遞到伺服器端(雖然麻煩點),然後在伺服器端,我們再對以上傳遞的Session ID 進行獲取和映射,這樣就手動完成了傳遞和匹配登錄用戶的工作了, Session 機制也得已繼續使用了。

小結

Cookie、Session 和Token 通常都是用來保存使用者登入資訊的技術,但三者的差異很大:Cookie 適用於簡單的狀態管理,Session 適用於需要保護使用者敏感資訊的場景,而Token 適用於狀態無關的身份驗證和授權。預設情況下Session 使用了Cookie 機制來傳遞Session ID,但在停用Cookie 的情況下,使用特殊的手段仍然可以傳遞Session ID,依然可以繼續使用Session 機制。而Token 是不在伺服器端保存會話資訊的,因此更適用於大型專案和分散式專案。