iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Mobile Development

Spring Boot+Android 30天 實戰開發 系列 第 22

【Day - 22】Spring Security 6.1.x:實現JWT身份驗證 (上)

  • 分享至 

  • xImage
  •  

1. 引言

在現代 Web 應用中,身份驗證(Authentication)是保護應用程式和資源的關鍵性質之一。它確保只有合法的使用者可以訪問受保護的內容,並為應用程式提供了一個安全的方式來識別和驗證使用者。

本文將深入探討如何實現身份驗證,並重點關注 JSON Web Tokens(JWT)這一現代身份驗證方法的使用。JWT 是一種開放標準(RFC 7519),它使用 JSON 物件來編碼和傳輸訊息,特別適用於分散式應用程式和 API 身份驗證。

我們將首先介紹 JWT 的基本概念,包括它的組成和工作原理。然後,我們將探討如何在 Spring Security 中整合 JWT,以實現強大的身份驗證機制。我們將提供實用的示例和配置,幫助您了解如何使用 JWT 來保護您的後端 API,同時限制資源的訪問。除此之外,我們還將討論 JWT 的刷新令牌和登出功能,以及如何在不同場景中選擇使用 JWT 身份驗證或傳統基於 Session 的驗證方式。

無論您是正在開發全新的應用程式,還是想要改進現有應用程式的安全性,本文都將為您提供有價值的信息和最佳實踐。讓我們開始探索 JWT 身份驗證的世界吧。

2. JWT 基本概念

JSON Web Token(JWT)是一種用於安全傳輸信息的開放標準,通常用於在網路上傳輸身份驗證和授權信息。JWT被廣泛應用於現代Web應用程式,特別是在分散式和微服務架構中。

JWT 的結構
一個JWT通常由三個部分組成,並且這些部分使用 句點" . " 進行分隔:

Header.Payload.Signature
  1. Header(標頭):JWT的標頭部分通常由兩個部分組成,它們也是JSON物件。第一部分是“alg”(algorithm)指定了用於生成簽名的加密算法,例如HMAC SHA256或RSA。第二部分是“typ”(type)指定了令牌的類型,通常設置為“JWT”。

    • 範例 Header:
      {
          "alg": "HS256",
          "typ": "JWT"
      }
      
  2. Payload(負載):JWT的負載部分包含稱為聲明(claims)的信息,這些聲明包含有關使用者或實體的數據,以及其他元數據。有兩種類型的聲明:

    • Registered claims:這些是一些預定義的聲明,常見的標準聲明類型:
      1. "iss"(Issuer):JWT的簽發者。
      2. "sub"(Subject):JWT所面向的使用者或實體。
      3. "aud"(Audience):JWT的受眾,即預期接收JWT的一方。
      4. "exp"(Expiration Time):JWT的過期時間。在這之後,JWT將不再有效。
      5. "nbf"(Not Before):JWT的生效時間,即在此時間之前JWT將不被接受。
      6. "iat"(Issued At):JWT的簽發時間。
      7. "jti"(JWT ID):JWT的唯一標識符。
    • Private claims:私有聲明是由JWT的簽發者自行定義的,用於包含應用程式特定的信息。這些聲明在JWT中不是預定義的,但可以根據需要添加。例如,你可以添加像 "role"(使用者角色)等自定義聲明,以便在應用程式中使用。
    • 範例 Payload:
      {
          "sub": "1234567890",
          "name": "Ian Liu",
          "iat": 1516239022,
          "exp": 1696221000
      }
      
  3. Signature(簽名):簽名部分是將標頭和負載進行簽名後的結果,以確保令牌在傳輸過程中未被篡改。簽名通常使用秘密的金鑰(或稱為密鑰)進行生成和驗證。

    JWT 的編碼
    JWT中的每一部分都是以Base64 URL安全編碼進行表示,這意味著它們可以被輕鬆地在HTTP環境中傳輸,且不會因為特殊字符而出現問題。編碼後的標頭、負載和簽名會用句點(.)分隔開,形成JWT的最終字串。

    • 編碼前的JWT結構:
    Header.Payload.Signature
    
    • 編碼後的JWT示例:
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IklhbiBMaXUiLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6IjE2OTYyMjEwMDAifQ.ZjGNjbuixzceLp3oteT-jaz6NMAUDYvfNDSovMIUcTo
    
  4. JWT線上解析工具

https://jwt.io/
這個線上工具可用於對JWT進行解析和編碼

圖片無法顯示

3. 選擇 JWT 或 Session

在實現身份驗證和授權的過程中,您可能需要選擇使用基於 Session 還是基於 JSON Web Token(JWT)的方式。每種方式都有其優點和缺點,取決於您的應用程式需求和場景。

基於 Session 的身份驗證

  • 優點:
    • 安全性:Session 存儲在伺服器端,因此可以更容易保護敏感信息。密碼等敏感數據通常不會存儲在客戶端。
    • 易於管理:Session 可以在伺服器端集中管理。當需要對使用者進行登入、登出、權限管理等操作時,可以輕鬆實現。
    • 有效期控制:可以輕鬆設定 Session 的有效期,以實現一定時間內的持久登入,或者實現自動登出功能。
  • 缺點:
    • 伺服器負載:伺服器需要在內存中存儲 Session 數據,尤其在大規模應用中可能會增加伺服器的負載。
    • 伺服器集群問題:在伺服器集群環境中,需要考慮 Session 的共享和同步,以確保不同伺服器之間的一致性。
    • 可擴展性:對於大規模應用,需要考慮伺服器集群的擴展性,以應對高流量。

基於 JWT 的身份驗證

  • 優點:
    • 無狀態性:JWT 是無狀態的,每個請求都包含了身份驗證信息,伺服器無需存儲 Session,這使得伺服器可以更輕鬆擴展。
    • 跨域支持:JWT 可以輕鬆在不同域名的伺服器之間共享身份驗證信息,這對於跨域請求非常有用。
    • 性能:由於不需要在伺服器端存儲 Session,JWT 的性能通常較好,特別是在大規模應用中。
  • 缺點:
    • 安全性:JWT 中的 payload 使用的是 base64 編碼,因此在 JWT 中不能存儲敏感信息。Session 存儲在伺服器端,相對來說更安全。
    • 一次性:JWT 是一次性的,無法在有效期內撤銷或修改。要實現撤銷功能,需要額外的機制。
    • 過期管理:JWT 過期後,必須重新簽發新的 JWT。這可能需要更多的邏輯來處理過期的情況。

選擇的理由
您應該根據您的應用程式需求和場景來選擇基於 Session 還是基於 JWT 的身份驗證方式:

  • 選擇基於 Session 的場景:如果您的應用程式需要高度的安全性,並且您可以控制伺服器集群,則基於 Session 可能是一個不錯的選擇。這特別適用於傳統的 Web 應用程式。
  • 選擇基於 JWT 的場景:如果您的應用程式需要無狀態性,或者需要支持跨域請求,或者需要高性能,則基於 JWT 可能更適合。這特別適用於現代的單頁應用(SPA)和分佈式應用程式。

無論您選擇哪種方式,都應該謹慎設計和實施身份驗證機制,並遵循最佳實踐以確保應用程式的安全性和效率。

下一節將深入介紹如何在 Spring Security 中實現 JWT 身份驗證。我們將提供具體的示例配置文件和設置,包括 JWT 的簽發和驗證過程,以確保應用程式的安全性。


上一篇
【Day - 21】Spring Security 6.1.x:實現基本認證(Basic Authentication)
下一篇
【Day - 23】Spring Security 6.1.x:實現JWT身份驗證 (中)
系列文
Spring Boot+Android 30天 實戰開發 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言