iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1
自我挑戰組

學習網頁開發系列 第 5

JWT vs Session

  • 分享至 

  • xImage
  •  

JWT 和 Session 皆為常見的認證(authentication)模式。值得注意的是,實作上來說,JWT、Session也可以達成授權(authorization),允許使用者獲取的特定資源。但這端看操作,授權也可以由伺服器端另外控制。

Authentication的目的

認證主要指的是身份認證。目的是讓使用者在一開始登入後,一定時間內不必重複認證身份,提升使用者體驗,同時簡化伺服端工作。有的像是進入遊樂園,暫時出園時只需在手臂上蓋個章,下次入園時便可快速通過,不必再拿出票卷或是身份證照,節省大家時間。當然此章也會有時間限制,過了特定時間後就作廢。網路的認證機制大抵如此,Session authentication 和 Token authentication 都是其中方法。

Session是什麼

當使用者登入時,伺服器在確認身份後,生出一個Session來紀錄此使用者目前正登入,並傳送相應的Session id到前端,一般存在瀏覽器的cookies裡。也因為伺服端儲存某些資料,此方法被歸類為stateful.

隨後客戶端的請求都會夾帶上此Session id,而伺服器就會拿這個id來比對現存的Session,確認此Request背後的身份是否正確。

JWT是什麼

JWT (Json Web Token)是token authentication的一種,不過由於它是目前最常見,因此以討論他為主。

使用者登入時,伺服器會在確認身份後生出一個JWT,並直接回傳給使用者。和Session不一樣的是,JWT並不會存任何副本或是資料在伺服端,因此他也被稱為Stateless method。

JWT包含了三塊:Header、Payload、Verify Signature三個部份。
JWT 樣板:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

代表含義:

//Header: algorithm and datatype
{
  "alg": "HS256",
  "typ": "JWT"
}
//Payload: data
{
  "sub": "1234567890", //使用者id
  "name": "John Doe",
  "iat": 1516239022 //簽發時間
  //另外常見 'exp',表示到期時間
}
//Verify Signature: 
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  SECRET_KEY//secret key
)

其中SECRET KEY 由伺服端掌握。只要當使用者回傳時,用選定的演算法解密,比對SECRET KEY是否與伺服器的相同,即可認證身份。

網站針對JWT執行細節有滿不錯的解釋

Refresh Token

由於JWT完全儲存於前端,被盜走後風險較大。因此常見防範手法包含縮短JWT的有效時間,這樣盜走後能亂用的時間較短。
但為了維持使用者體驗,免除反覆登入之擾,這時會另存一個refresh token到前端,並且在JWT失效時傳此refresh token到後端請求一個新的JWT。
或許你已經發現了,但refresh token此時就需要一個對照的東西存於後端,不然他本身就只是另一個JWT,意義不大。因此這個方法也常被稱作Session + JWT,因為 Refresh token此時跟Session 的操作模式非常類似。

存哪裡

這裡指的是用戶端存在哪。
對Session 而言,大部分Session id 都會放在Session cookie裡。由於發送請求時,伺服器會將同網域的cookie內容一起送出,所以十分適合。不過cookie就會需要擔心csrf,這時候就要再加上Http cookie有諸多保護措施,例如httponly, samesite等等設置。勁量降低惡意攻擊的風險。

相較之下,許多人會將JWT裝在localStorage,發送請求時自己用JS抓來送。這樣的問題就是可能會受到XSS攻擊,導致JWT外流。尤其假如掛到含有惡意腳本的CDN時。不過就像前面提到的refreseh token,總有很多辦法可以解決。而存在localstorage好過cookie的理由之一在於,cookie的容量相較於localstorage小很多。另外,要對cookie內容進行操作也比localstorage麻煩上許多。

比對

功能 Session JWT
伺服端儲存 需要有特定專區儲存Session資訊 無須另闢專區,只要有SECRET KEY即可
使認證失效 後端可以直接設定 很不方便
擴張 Session必須存在一個共用的地方(例如redis),多個伺服器都要連到它。越是多伺服器,延遲的問題越可能發生 相對簡單,只要多個伺服器都有同個SECRET KEY 即可

上一篇
Python super() 到底在幹嘛
下一篇
Django Model 繼承的方法
系列文
學習網頁開發13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言