2020-11-05|閱讀時間 ‧ 約 6 分鐘

JWT Authentication

JWT全名JSON Web Token,因符合RESTful API無狀態原則而誕生。
傳統我們通常會用cookie/session的方式來做身分認證,也就是user登入後,用session id當作一種token,來做身份認證。
然而用session這種方法server會有額外的儲存負擔,查詢也會需要時間,加上一般production server不會只有一台,如果用session的話會有server之間如何共享session的問題。(當然如果您的SLB是by ip分流那就另當別論了) 另外,使用JWT不會有像cookie一樣可能有無法跨域傳送的問題,也不會有CSRF攻擊的問題,因為我們不會把JWT儲存在cookie,不會讓瀏覽器自動送出,通常是駭客會透過攔截封包來擷取JWT,只不過還是建議使用HTTPS傳輸比較安全。
JWT字串由header, payload, signature三個部分組成,各自編碼後,用.串接起來即成為JWT字串。 JWT = Header.Payload.Signature

Header:
組成如下,alg是token被加密的演算法,typ是指token的type。 { "alg": "HS256", "typ": "JWT" }
把這個json做base64 encode即為Header。

Payload:
這邊是放聲明訊息的地方,有以下幾種定義:
1. 標準聲明(Registered claims)
JWT規定的標準聲明,只是建議可以放,沒有強制一定要放。
2. 私有聲明(Private claims)
可自行定義的聲明,通常會放user的不敏感資料。
3. 公有聲明(Public claims)
實務上不太會需要用到,有時間再來研究。
Payload組成範例: { "iss": "http://www.example.com", "exp": 1525318201, "data": { "user_id": 1, "user_name": "Vic" } }
其中iss = JWT簽發者, exp = JWT的過期時間,這兩個都是標準聲明。標準聲明還有很多定義,可自行查詢。 data的部分就是自定義的user資料。
把這個json做base64 encode即為Payload。

Signature:
Signature是這樣組成的: HMAC-SHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
其中secret=金鑰,只有伺服器知道這組金鑰。 HS256 = HMAC-SHA256
將header和payload json data做base64UrlEncode編碼後,用.來串接成data string,再使用header中指定的hash演算法HS256來對data string使用金鑰進行加密,產生簽名(signature)。

根據本文提到的範例,最終產生的JWT token如下圖: Header.Payload.Signature 紅.紫.藍
JWT驗證流程如下: 1. 在前端打後端登入api,且user確認登入成功後,server會回傳這組JWT Token給前端。 2. 前端收到JWT Token後,一般會將其儲存在local storage中。 3. 之後前端要存取後端API的時候,需在header帶上這組token: Authorization: Bearer ${JWT token} 假設JWT token是abc即為: Authorization: Bearer abc 4. 後端收到token後會驗證token有效性,決定是否可以存取此api。

分享至
成為作者繼續創作的動力吧!
小弟是一位軟體工程師,樂於幫助他人,撰寫技術文章除了幫助自己複習以外,也希望可以幫助到他人,若文章內容有誤,還請大大不吝給予指教!
從 Google News 追蹤更多 vocus 的最新精選內容從 Google News 追蹤更多 vocus 的最新精選內容

發表回應

成為會員 後即可發表留言