JWT(JSON Web Token) 和 Session 的差別

目的

透過這篇文章理解JWT(JSON Web Token)與Session的差異,以及為何現在大家都用JWT而不是用傳統的Session儲存使用者的資訊,本篇文章的案例都透過登入行為做解說。

緣由

這篇文章主要針對兩者的差異,其實我一直以來只用過session做過使用者狀態傳輸,但是因為工作使用到了Jhisper框架開始嘗試JWT,不過因為這套框架已經將JWT都完整包好直接使用就好,所以不是非常了解,直到有天需要自己寫Spring Security後才發現JWT的奧妙,但是在嘗試的過程中一直不知道為啥不使用Session就好,就開始展開兩者VS的冒險,也有了這篇文章。

Cookie & Session

如果要討論Session的話首先我們必須先理解Cookie是甚麼。

Cookie

我們可以從Wiki上得知

因為HTTP協定是無狀態的,即伺服器不知道用戶上一次做了什麼,這嚴重阻礙了互動式Web應用程式的實現。在典型的網路購物場景中,用戶瀏覽了幾個頁面,買了一盒餅乾和兩瓶飲料。最後結帳時,由於HTTP的無狀態性,不通過額外的手段,伺服器並不知道用戶到底買了什麼,所以Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一。伺服器可以設定或讀取Cookies中包含資訊,藉此維護用戶跟伺服器對談中的狀態。

但是使用Cookie會有以下的缺陷

辨識不精確

如果在同一台機器上使用多個瀏覽器,每個瀏覽器在不同的儲存位置儲存 Cookie,因此,Cookie 並不能定位到一個具體的人,而是用戶,電腦和瀏覽器的組合。

不準確的狀態

如果用戶在取得了一個 Cookie 之後,點擊了瀏覽器的"回退"按鍵,則瀏覽器的狀態和取得Cookie 的狀態就出現了不一致.例如, 如果網站基於 Cookie 技術實現了購物車的應用,當用戶添加了物品後點擊了"回退"按鍵, 購物車的物品狀態可能並沒有發生變化.

隱私、安全和廣告

  • Cookie 是沒有加密的
  • 案例
    Cookies在某種程度上說已經嚴重危及用戶的隱私和安全。其中的一種方法是:一些公司的高層人員為了某種目的(譬如市場調研)而存取了從未去過的網站(通過搜尋引擎查到的),而這些網站包含了一種叫做網頁臭蟲的圖片,該圖片透明,且只有一個像素大小(以便隱藏),它們的作用是將所有存取過此頁面的電腦寫入Cookie。而後,電子商務網站將讀取這些Cookie資訊,並尋找寫入這些Cookie的網站,隨即傳送包含了針對這個網站的相關產品廣告的垃圾郵件給這些進階人員。

Session

了解Cookie後我們可已開始討論Session是甚麼,Session是將使用者的狀態儲存在Sever端的方法,而實踐方法如下圖

執行步驟

  1. 使用者登入
  2. 伺服器端偵測到使用者登入並且將資訊寫入Session中,並且將Cookie資訊回傳回使用者端,然後告訴瀏覽器要將這資訊儲存到Cookie中
  3. 使用者再次登入或是針對此網站做其他操作時,就會連帶將Cookie傳到Server端,並且對Session作相對應的處理
  4. Server端可以針對此資訊做解析再次回傳給使用者

問題

  • 假設今天有超過十萬個使用者使用的話那Server端就會需要將這些資訊儲存在記憶體中,會嚴重的占用Server的記憶體
  • 而且如同剛剛Cookie上的缺陷也會在這樣的Client-Server方法中浮現

解決方法 JWT!!

JWT (JSON Web token)

介紹

其實JWT是一種Token Based的方法,只是他的Token是使用JSON去實作,使用JSON的原因我個人認為如下

  • JSON格式是Javascript的物件格式,Client端可以直接接收就進入前端程式開始使用不需做過多處理
  • JSON中的資料,擴張非常彈性與簡便,而且大小和XML相比明顯簡潔許多

下方是JWT實際的流程圖

執行步驟

  1. 使用者登入

  2. 伺服器端偵測到使用者登入並且將資訊包裝成JWT,並且將資訊傳回給Client端

  3. Client端接收到JWT後,依照不同Client端開發策略將JWT儲存(大部分儲存於Local Storage中)

  4. Client再次對網站做其他行為,則會將JWT進行處理(可能包裝使用者的操作資訊),並且將JWT包裝於Http的Header之中,傳給Server端

  5. Server端可以針對Client端的JWT資訊作相對應處理再回應回去

其實步驟與Cookie-Session很相似,但是關鍵差別如下

與Cookie-Session的關鍵差別

  1. Cookie無法加密 / JWT可以根據開發者的需求進行加密(因為是由自己開發的程式掌控)
  2. Seesion會占用Server的記憶體 / JWT Server端不會做任何儲存,會將資訊儲存在Client端中

當然,使用JWT也是跟Cookie-Session方法一樣,會有占用傳輸的問題(需要將資訊儲存在Header之中傳送),而且甚至會更嚴重,但根據上方的兩個關鍵差別,可以知道只要套用JWT就可以提升網站的安全性與擴張性。

  • 安全性 : 因為JWT可以進行加密
  • 擴張性 : 因為Seesion需要占用Server記憶體,所以當使用者變多後,Server會負荷不了需要不斷的加購記憶體,而JWT完全沒這煩惱(因為資訊儲存在Client端)

參考資源

留言

這個網誌中的熱門文章

Java Lambda Map篇

(InterviewBit) System Design - Design Cache System

設計模式 - 享元模式 (Structural Patterns - Flyweight Design Pattern)