iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Software Development

埋藏在後端工程下的地雷與寶藏系列 第 4

Day-4 | JWT 給你的網頁加個“安全鎖”

  • 分享至 

  • xImage
  •  

因為只使用過 ip 白名單來限制 ip 的存取,一直都沒有機會使用到JWT,但之前有自學了解一下要如何使用,透過這次鐵人賽剛好把學習的整理複習一下,並嘗試應用在 Python 框架上。

What is JWT

JWT(Json Web Token) 是一種開放標準(RFC 7519),格式為 JSON,它主要的目的是確保訊息在網路傳輸過程中的完整性和有效性,比較常被使用在驗證和授權。
主要執行的方式,是使用者登入後會跟伺服器索取 JWT,並將 JWT 儲存在本地端(如 localStorage 或 sessionStorage)並在每次發起請求時附加到 Authorization header中,就不用在重複輸入密碼,直到該JWT 過期。

  • e.g.:
    • 你跟房東訂好租期後,他會給你大門的密碼,在這段期間你就能自由進出房子,租期時間到了房東就會換密碼,你就需要再次和房東索取才能自由進出。

組成部分

JWT 由三個部分組成:

  • Header
  • Payload
  • Signature

Header:
包含加密的演算法(如 HS256)和 token 類型(JWT)。

  • alg 常見的演算法有:
    • AES:
      • HS256:HMAC 使用 SHA-256(HMAC-SHA-256),這是最常用的對稱加密演算法之一。
    • RSA:
      • RS256:RSA 使用 SHA-256(RSA-SHA-256),使用一對公鑰和私鑰進行簽名和驗證。
  • e.g.:
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    

Payload:
主要放的是claims(聲明)的內容,也就是主要想要傳遞的訊息。claims 主要分為 Registered claims、Public claims 或 Private claims。

1. Registered Claims
Registered Claims 主要放的是一些常用公認的一些訊息。
e.g. :

  • iss(Issuer): token 的發行者
  • sub(Subject): token 使用的主要對象,如使用者的 ID。
  • aud(Audience): 表示這個 token 是發給誰的。確保 token 只被指定的應用所使用。
  • exp(Expiration Time): Token 的過期時間,以秒為單位。
  • nbf(Not Before): Token 的生效時間,表示 token 在這個時間之前沒辦法使用。
  • iat(Issued At): Token 的發行時間。
  • jti(JWT ID): 每個 token 都會有唯一的 id,避免重複發放。

2. Public Claims
Public Claims 主要指的是有在 IANA JSON Web Token 註冊的聲明。

  • e.g. :
    • role: 用戶的角色(如 admin、user),通常用於授權控制。

3. Private Claims
Private Claims 是自行定義的 Claims,這些 Claims 不需要在 IANA JSON Web Token中進行註冊,但需要與所有使用該 token 的使用者達成共識。

  • e.g. :

    • user_id、department等。
  • e.g. :

    {
      "iss": "https://example.com",       // Registered Claims
      "sub": "0000000001",                // Registered Claims
      "aud": "https://example.com",       // Registered Claims
      "exp": 1694131200,                  // Registered Claims
      "nbf": 1694044800,                  // Registered Claims
      "iat": 1694044800,                  // Registered Claims
      "jti": "00000009",                  // Registered Claims
      "role": "admin",                    // Public Claims
      "name": "Yusinz",                   // Public Claims
      "user_id": "123456",                // Private Claims
      "department": "Engineering",        // Private Claims
    }
    

使用 Payload 的注意事項

  • 安全性: 雖然 JWT 可以使用 Signature 來確保資料的完整性和真實性,但 Payload 通常是以 Base64 URL 編碼形式儲存在 Token 中的,因此盡量不要在其中存放敏感的資訊。
  • e.g.:
    • password

Signature:
用來驗證 token 的完整性和真實性。Signature 是通過對 Header 和 Payload 進行編碼,並使用秘密(或私鑰)進行簽名來生成的。

  • 將 Header 和 Payload 都進行 Base64 URL 編碼,去除掉可能在 URL 中不安全的符號,如 +、/ 和 =。
  • 將編碼後的兩組字串用 "."進行連接。
  • 最後使用Header中的 alg 和保存在server 的 secret,對連接後的 Header 和 Payload 進行加密。
  • e.g.:
    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      secret
    )
    

JWT的優點

  • 無狀態: server 不再需要儲存 session,所有必要的訊息都包含在 token 中。
  • 輕量: JWT 的結構輕便,適合用於 URL、HTTP header或 POST 參數中。
  • 可擴展性: 跨語言,因為 json 格式大部分語言都可使用。

需注意的點

  • 過期問題: JWT 一旦生成,其內容(如用戶角色和權限)無法更改,過期時間需要謹慎設置。
  • 無法撤銷: 一旦發行,JWT 在有效期內無法撤銷,這可能導致在使用者退出或權限變更時的安全風險。
  • 安全問題: 可能面臨 XSS 或 CSRF攻擊,須有效防範可能的攻擊。

這些雖然是需要注意的點,但其實都有一些解法,只是這裡就不多解釋,有興趣深入了解的,google 應該就很多答案了!

JWT 流程

https://ithelp.ithome.com.tw/upload/images/20240918/20150927eZyy4Kw8XE.png
圖片來源

最後推薦可以去一個網站,他可以在裡面分析和產生 JWT ,實際嘗試更能了解實際是如何運作的!

https://ithelp.ithome.com.tw/upload/images/20240908/20150927AgcE4Wa469.png

Reference:


上一篇
Day-3 | 怎麼讓你的 API 更 Restful !
下一篇
Day-5 | What is CORS !?
系列文
埋藏在後端工程下的地雷與寶藏12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言