溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBootSecurity中JWT的使用方法

發(fā)布時間:2021-09-28 09:44:08 來源:億速云 閱讀:115 作者:柒染 欄目:大數(shù)據(jù)

本篇文章為大家展示了SpringBootSecurity中JWT的使用方法,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

JWT 使用

前面簡單介紹了把默認的頁面登錄改為前后端分離的接口異步登錄的方法,可以幫我們實現(xiàn)基本的前后端分離登錄功能。但是這種基本的登錄和前面的頁面登錄還有一個一樣的地方,就是使用session和cookie來維護登錄狀態(tài),這種方法的問題在于,擴展性不好。單機當然沒有問題,如果是服務器集群,或者是跨域的服務導向架構,就要求 session 數(shù)據(jù)共享,每臺服務器都能夠讀取 session。

一種解決方案是 session 數(shù)據(jù)持久化,寫入redis或別的持久層。各種服務收到請求后,都向持久層請求數(shù)據(jù)。這種方案的優(yōu)點是架構清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。

另一種方案是服務器索性不保存 session 數(shù)據(jù)了,所有數(shù)據(jù)都保存在客戶端,每次請求都發(fā)回服務器。JWT 就是這種方案的一個代表。關于JWT的理論知識,建議參考 阮一峰 大神寫的教程 :JSON Web Token 入門教程,這是我認為可能是寫的最清晰的一個,下面的jwt的實現(xiàn)也是根據(jù)此教程來實現(xiàn)。

具體的理論知識可以參考教程,這里簡單說下流程,用戶登錄成功后,在header中返回用戶一個token信息,這個信息里面包含了加密的用戶信息和數(shù)字簽名,最重要的還有過期時間,客戶端接到后,每次訪問接口header中都帶著這個token,服務端驗證成功后就表示處于登錄狀態(tài),過期后再從新獲取即可。

具體的token內(nèi)容包含了頭部(加密信息),載體(用戶信息),簽名(簽名兩個部分的前面)三大塊,三大塊之間用英文句號(也就是 ".")連接起來,組成一個完整的token信息

流程設計

根據(jù)前面的理論知識,我們來設計一下如何使用jwt。首先我們使用jwt,就可以不再使用session和cookie,所以第一步就是:

  1. 在security配置文件中配置session為無狀態(tài)。

然后考慮構建jwt消息體,有三個部分,第一個部分就是頭部,內(nèi)容是加密類型:

SpringBootSecurity中JWT的使用方法

上面代碼中,alg屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌統(tǒng)一寫為JWT,最后,將上面的 JSON 對象使用 Base64URL 算法轉成字符串,作為第一部分。所以第二步就是:

  1. 在security配置文件中配置session為無狀態(tài)。

  2. 確定header信息格式

下一步確定第二部分,消息載體(Payload),這也是一個json對象,用來存放實際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個官方字段,供選用:

SpringBootSecurity中JWT的使用方法

當然除了這些還可以加一些其它內(nèi)容,比如用戶信息,這個 JSON 對象也要使用 Base64URL 算法轉成字符串,所以第三步和第四步就是:

  1. 在security配置文件中配置session為無狀態(tài)。

  2. 確定header信息格式

  3. 確定消息體

  4. 使用 HMAC SHA256 算法 對header和消息體進行簽名作為第三部分

現(xiàn)在token的消息基本組合完成了,用戶登錄成功和客戶端訪問接口,都要把token放在header里面,名字是 Authorization 。所以最后一步就是,客戶端正常訪問非登錄等接口時,驗證token的合法性,所以,總體設計流程如下:

  1. 在security配置文件中配置session為無狀態(tài)。

  2. 確定header信息格式

  3. 確定消息體

  4. 使用 HMAC SHA256 算法 對header和消息體進行簽名作為第三部分

  5. 添加過濾器,驗證token合法性

修改配置類

上面的流程設計完了,下面我們按照流程修改項目,首先修改security配置類:

SpringBootSecurity中JWT的使用方法

配置完后,啟動項目,訪問登錄,登錄成功后可以看到,沒有任何cookie保存下來。

定義JWT工具類

首先來定義幾個常量:

SpringBootSecurity中JWT的使用方法

然后定義Base64URL 算法編碼和解碼方法:

SpringBootSecurity中JWT的使用方法

然后定義HmacSHA256 加密算法和獲取簽名的方法:

SpringBootSecurity中JWT的使用方法

最后來設計一個簡單驗證token的方法:

SpringBootSecurity中JWT的使用方法

這樣jwt工具類就設計好了,目前這幾個方法足夠操作token內(nèi)容。

定義JWT消息對象

下面來定義jwt的內(nèi)容,其實內(nèi)容很簡單,就三個部分,因此,定義三個字段即可:

SpringBootSecurity中JWT的使用方法

來看一下構造方法,

SpringBootSecurity中JWT的使用方法

這個構造方法很便捷,使用它創(chuàng)建對象以后,jwt的三個部分基本都完成了,header部分和payload部分都編碼了,簽名也完成了,因此下面重寫toString方法直接可以生成token:

SpringBootSecurity中JWT的使用方法

從這里可以看出,token整體默認是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。因此不要把密碼等重要信息放入token。

修改登錄成功處理器

用戶登錄成功后,不再把session發(fā)給用戶,而是把jwt發(fā)送給用戶,因此修改登錄成功處理器如下:

SpringBootSecurity中JWT的使用方法

注意上面手動把用戶的密碼信息設置為null。這里為了方便,直接使用fastjson組合對象。

修改實體類

帶著token訪問接口的時候,需要把token轉回登錄用戶對象,因此我們的用戶實體類和token中帶的字段名字一致,來修改一下,先看角色實體類:

SpringBootSecurity中JWT的使用方法

再看用戶實體類:

SpringBootSecurity中JWT的使用方法

可以看到,基本的原則就是修改的名字和父類的必要字段名字一致就行,這也是建議的字段名字。

編寫token驗證過濾器

我們把security的session改為無狀態(tài)后,雖然不再傳遞session,但是security的過濾器并沒有失效,因此造成的效果就是登錄成功后,訪問接口顯示未登錄?,F(xiàn)在我們使用token就要在登錄前加一個驗證token的過濾器,驗證通過后直接把信息放到SecurityContextHolder中。這樣每次登錄靠驗證token來判斷是否登錄,不再靠session。來看這個過濾器:

SpringBootSecurity中JWT的使用方法

這個過濾器很簡單,繼承了 GenericFilterBean 類,直接獲取token,判斷token不為空,驗證token,并從token的payload中取出用戶信息,放入SecurityContextHolder中,驗證失敗或者token過期直接返回token錯誤。邏輯很簡單。

最后在security類中,把這個過濾器配置到前面:

SpringBootSecurity中JWT的使用方法

這樣我們自定義的jwt流程就完成了??梢栽趐ostman中測試一下,首先是登錄:

SpringBootSecurity中JWT的使用方法

登錄成功后,可以看到header中放著token的信息,然后使用token放入另一個接口的header中訪問接口,可以看到訪問成功:

SpringBootSecurity中JWT的使用方法

有興趣的可以debug跟蹤一下流程。

JWT的幾個特點

  • (1)JWT 默認是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。

  • (2)JWT 不加密的情況下,不能將秘密數(shù)據(jù)寫入 JWT。

  • (3)JWT 不僅可以用于認證,也可以用于交換信息。有效使用 JWT,可以降低服務器查詢數(shù)據(jù)庫的次數(shù)。

  • (4)JWT 的最大缺點是,由于服務器不保存 session 狀態(tài),因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發(fā)了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

  • (5)JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權限。為了減少盜用,JWT 的有效期應該設置得比較短。對于一些比較重要的權限,使用時應該再次對用戶進行認證。

  • (6)為了減少盜用,JWT 不應該使用 HTTP 協(xié)議明碼傳輸,要使用 HTTPS 協(xié)議傳輸。

上述內(nèi)容就是SpringBootSecurity中JWT的使用方法,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI