天天看點

com.auth0.java jwt_【java】使用jwt進行認證授權

傳統的web應用使用session來維護使用者與伺服器之間的狀态,使用者送出使用者名密碼到伺服器,伺服器生成會話id,并将驗證通過的使用者資訊存到session中(記憶體or資料庫),會話id會寫出到cookie。

使用者登入之後的操作,都會附帶包含sessionId的cookie,伺服器根據使用者端傳來的sessionId擷取使用者資訊,會話的有效期,包括使用者登出等操作都依賴對session的操作,如下圖:

com.auth0.java jwt_【java】使用jwt進行認證授權

----

基于session的認證使用者資訊存在了服務端記憶體中,在分布式環境中session是需要同步的。出現了基于token的認證方式,其實本質和session沒什麼差別。使用者送出登入資訊後,服務端驗證通過後頒發令牌。下圖是以redis為例,将token和使用者資訊儲存到redis,用戶端再次通路服務端時,會攜帶token,服務端通過token擷取使用者資訊。會話的有效期,使用者的登出隻需要操作redis中的token即可,如下圖:

com.auth0.java jwt_【java】使用jwt進行認證授權

當然了,token本身也是可以包含一些使用者非敏感資訊減少查庫,包含數字簽名以防資料篡改,下面看下jwt(json web token)。----

從名稱可以看出jwt還是一個token,它有自己的規範,由标頭.有效載荷.簽名組成。頭用來描述雜湊演算法,然後是使用者資料,最後是一個數字簽名。

com.auth0.java jwt_【java】使用jwt進行認證授權

----

先來看下jwt的java實作。com.auth0java-jwt3.10.2

使用jwt通常隻需要兩個步驟,1通過jwt來生成token,2驗證token。JwtUtil String = String = String MapStringStringclaimsAlgorithm algorithm = Algorithm.JWTCreator.Builder builder = JWT..withIssuer.withExpiresAtDateUtils.Dateclaims.forEachbuilder::withClaimbuilder.signalgorithmException eRuntimeExceptioneMapStringStringString tokenMapStringStringret = Maps.Algorithm algorithm = Algorithm.JWTVerifier verifier = JWT.algorithm.withIssuer.buildDecodedJWT jwt =  verifier.verifytokenMapStringClaimmap = jwt.getClaimsRuntimeExceptioneret

以上就是一個jwt的簡單示例,用戶端攜帶token請求時,服務端可以校驗jwt的簽名及有效時間,校驗通過則放行,否則拒絕請求。

----優點:可以看到使用jwt自身就可以完成認證,可以減少資源連接配接,也可以避免跨域認證請求,自帶資訊也可以用于資料傳遞。

缺點:可以看到一旦生成token,就無法回收,token的管理(重新整理有效期&登出)需要其它補償機制(如使用redis管理token);預設有效載荷隻是經過base64編碼,隻是為了友善傳輸,并未加密(也可以自行加密),敏感資料不應該放到jwt中。