欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA后端實(shí)現(xiàn)JWT令牌的示例

 更新時(shí)間:2024年12月30日 10:51:49   作者:JKQingNing  
本文主要介紹了JAVA后端實(shí)現(xiàn)JWT令牌的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

首先解釋一下JWT,在此之前,我們需要明確為什么需要JWT

登陸校驗(yàn)

其實(shí)最常見的應(yīng)用場景就是登陸校驗(yàn),我們希望某個(gè)用戶在初次打開網(wǎng)址時(shí),首先應(yīng)該進(jìn)行登陸操作,而不是直接訪問某個(gè)功能,并且在登陸之后,訪問其他功能時(shí)不需要再次登陸。在此前提下,應(yīng)運(yùn)而生三種登陸校驗(yàn)方式,下面我們一一講解。

會(huì)話跟蹤

什么是會(huì)話,我們摒棄其他科普詞條繁雜的專業(yè)詞匯介紹,我們就這樣認(rèn)為:你去買東西,從你走進(jìn)了一家商店開始,你就開始了你和“商店”的會(huì)話,你買完東西走出商店,此次會(huì)話結(jié)束。在這里面,“你”就是瀏覽器,“商店”就是服務(wù)器。我們買東西,不可能每買一個(gè),都需要重新進(jìn)入商店(登錄),也不可能不進(jìn)入商店,就可以買東西(舉例,以線下商店為例)。

接下來我們正式講解什么是會(huì)話跟蹤,詞條解釋是這樣的:一種維護(hù)瀏覽器狀態(tài)的方法,服務(wù)器需要識(shí)別多次請(qǐng)求是否來自于同一瀏覽器,以便在同一次會(huì)話的多次請(qǐng)求間共享數(shù)據(jù)。

為什么我們需要會(huì)話跟蹤,這是因?yàn)镠TTP協(xié)議是一種無狀態(tài)的協(xié)議。所謂無狀態(tài),指的是每一次請(qǐng)求都是獨(dú)立的,下一次請(qǐng)求并不會(huì)攜帶上一次請(qǐng)求的數(shù)據(jù)。而瀏覽器與服務(wù)器之間進(jìn)行交互,基于HTTP協(xié)議也就意味著現(xiàn)在我們通過瀏覽器來訪問了登陸這個(gè)接口,實(shí)現(xiàn)了登陸的操作,接下來我們?cè)趫?zhí)行其他業(yè)務(wù)操作時(shí),服務(wù)器也并不知道這個(gè)員工到底登陸了沒有。因?yàn)镠TTP協(xié)議是無狀態(tài)的,兩次請(qǐng)求之間是獨(dú)立的,所以是無法判斷這個(gè)員工到底登陸了沒有。因此我們需要會(huì)話跟蹤,去“記錄”交互操作。

我們有三種會(huì)話跟蹤技術(shù),分別是:cookie、session、令牌(只需了解jwt的可以跳過前兩項(xiàng)介紹)

cookie

cookie 是客戶端會(huì)話跟蹤技術(shù),它是存儲(chǔ)在客戶端瀏覽器的,我們使用 cookie 來跟蹤會(huì)話,我們就可以在瀏覽器第一次發(fā)起請(qǐng)求來請(qǐng)求服務(wù)器的時(shí)候,我們?cè)诜?wù)器端來設(shè)置一個(gè)cookie。

比如第一次請(qǐng)求了登錄接口,登錄接口執(zhí)行完成之后,我們就可以設(shè)置一個(gè)cookie,在 cookie 當(dāng)中我們就可以來存儲(chǔ)用戶相關(guān)的一些數(shù)據(jù)信息。比如我可以在 cookie 當(dāng)中來存儲(chǔ)當(dāng)前登錄用戶的用戶名,用戶的ID。

服務(wù)器端在給客戶端在響應(yīng)數(shù)據(jù)的時(shí)候,會(huì)自動(dòng)的將 cookie 響應(yīng)給瀏覽器,瀏覽器接收到響應(yīng)回來的 cookie 之后,會(huì)自動(dòng)的將 cookie 的值存儲(chǔ)在瀏覽器本地。接下來在后續(xù)的每一次請(qǐng)求當(dāng)中,都會(huì)將瀏覽器本地所存儲(chǔ)的 cookie 自動(dòng)地?cái)y帶到服務(wù)端。

切記,以上三步都是自動(dòng)進(jìn)行。那么為什么會(huì)自動(dòng)進(jìn)行?

因?yàn)?cookie 它是 HTP 協(xié)議當(dāng)中所支持的技術(shù),而各大瀏覽器廠商都支持了這一標(biāo)準(zhǔn)。在 HTTP 協(xié)議官方給我們提供了一個(gè)響應(yīng)頭和請(qǐng)求頭:

  • 響應(yīng)頭 Set-Cookie :設(shè)置Cookie數(shù)據(jù)的

  • 請(qǐng)求頭 Cookie:攜帶Cookie數(shù)據(jù)的

接下來在服務(wù)端我們就可以獲取到 cookie 的值。我們可以去判斷一下這個(gè) cookie 的值是否存在,如果不存在這個(gè)cookie,就說明客戶端之前是沒有訪問登錄接口的;如果存在 cookie 的值,就說明客戶端之前已經(jīng)登錄完成了。這樣我們就可以基于 cookie 在同一次會(huì)話的不同請(qǐng)求之間來共享數(shù)據(jù)。

我們使用代碼實(shí)現(xiàn):

@Slf4j
@RestController
public class SessionController {

    //設(shè)置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response){
        response.addCookie(new Cookie("login_username","itheima")); //設(shè)置Cookie/響應(yīng)Cookie
        return Result.success();
    }
	
    //獲取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("login_username")){
                System.out.println("login_username: "+cookie.getValue()); //輸出name為login_username的cookie
            }
        }
        return Result.success();
    }
}  

訪問c1接口,設(shè)置Cookie,http://localhost:8080/c1

我們可以看到,設(shè)置的cookie,通過響應(yīng)頭Set-Cookie響應(yīng)給瀏覽器,并且瀏覽器會(huì)將Cookie,存儲(chǔ)在瀏覽器端。

訪問c2接口 http://localhost:8080/c2,此時(shí)瀏覽器會(huì)自動(dòng)的將Cookie攜帶到服務(wù)端。

  • 優(yōu)點(diǎn):HTTP協(xié)議中支持的技術(shù)(像Set-Cookie 響應(yīng)頭的解析以及 Cookie 請(qǐng)求頭數(shù)據(jù)的攜帶,都是瀏覽器自動(dòng)進(jìn)行的,是無需我們手動(dòng)操作的)

  • 缺點(diǎn):

session

其實(shí)session的底層就是基于我們剛才所介紹的 Cookie 來實(shí)現(xiàn)的。

  • 獲取Session

  • 如果我們現(xiàn)在要基于 Session 來進(jìn)行會(huì)話跟蹤,瀏覽器在第一次請(qǐng)求服務(wù)器的時(shí)候,我們就可以直接在服務(wù)器當(dāng)中來獲取到會(huì)話對(duì)象Session。如果是第一次請(qǐng)求Session ,會(huì)話對(duì)象是不存在的,這個(gè)時(shí)候服務(wù)器會(huì)自動(dòng)的創(chuàng)建一個(gè)會(huì)話對(duì)象Session 。而每一個(gè)會(huì)話對(duì)象Session ,它都有一個(gè)ID(示意圖中Session后面括號(hào)中的1,就表示ID),我們稱之為 Session 的ID。

  • 響應(yīng)Cookie (JSESSIONID)

    接下來,服務(wù)器端在給瀏覽器響應(yīng)數(shù)據(jù)的時(shí)候,它會(huì)將 Session 的 ID 通過 Cookie 響應(yīng)給瀏覽器。其實(shí)在響應(yīng)頭當(dāng)中增加了一個(gè) Set-Cookie 響應(yīng)頭。這個(gè) Set-Cookie 響應(yīng)頭對(duì)應(yīng)的值是不是cookie? cookie 的名字是固定的 JSESSIONID 代表的服務(wù)器端會(huì)話對(duì)象 Session 的 ID。瀏覽器會(huì)自動(dòng)識(shí)別這個(gè)響應(yīng)頭,然后自動(dòng)將Cookie存儲(chǔ)在瀏覽器本地。

  • 查找Session

    接下來,在后續(xù)的每一次請(qǐng)求當(dāng)中,都會(huì)將 Cookie 的數(shù)據(jù)獲取出來,并且攜帶到服務(wù)端。接下來服務(wù)器拿到JSESSIONID這個(gè) Cookie 的值,也就是 Session 的ID。拿到 ID 之后,就會(huì)從眾多的 Session 當(dāng)中來找到當(dāng)前請(qǐng)求對(duì)應(yīng)的會(huì)話對(duì)象Session。

    這樣我們是不是就可以通過 Session 會(huì)話對(duì)象在同一次會(huì)話的多次請(qǐng)求之間來共享數(shù)據(jù)了?好,這就是基于 Session 進(jìn)行會(huì)話跟蹤的流程。

我們使用代碼實(shí)現(xiàn):

@Slf4j
@RestController
public class SessionController {

    @GetMapping("/s1")
    public Result session1(HttpSession session){
        log.info("HttpSession-s1: {}", session.hashCode());

        session.setAttribute("loginUser", "tom"); //往session中存儲(chǔ)數(shù)據(jù)
        return Result.success();
    }

    @GetMapping("/s2")
    public Result session2(HttpServletRequest request){
        HttpSession session = request.getSession();
        log.info("HttpSession-s2: {}", session.hashCode());

        Object loginUser = session.getAttribute("loginUser"); //從session中獲取數(shù)據(jù)
        log.info("loginUser: {}", loginUser);
        return Result.success(loginUser);
    }
}

訪問 s1 接口,http://localhost:8080/s1

請(qǐng)求完成之后,在響應(yīng)頭中,就會(huì)看到有一個(gè)Set-Cookie的響應(yīng)頭,里面響應(yīng)回來了一個(gè)Cookie,就是JSESSIONID,這個(gè)就是服務(wù)端會(huì)話對(duì)象 Session 的ID。

訪問 s2 接口,http://localhost:8080/s2

接下來,在后續(xù)的每次請(qǐng)求時(shí),都會(huì)將Cookie的值,攜帶到服務(wù)端,那服務(wù)端呢,接收到Cookie之后,會(huì)自動(dòng)的根據(jù)JSESSIONID的值,找到對(duì)應(yīng)的會(huì)話對(duì)象Session。 兩次請(qǐng)求,獲取到的Session會(huì)話對(duì)象的hashcode是一樣的,就說明是同一個(gè)會(huì)話對(duì)象。而且,第一次請(qǐng)求時(shí),往Session會(huì)話對(duì)象中存儲(chǔ)的值,第二次請(qǐng)求時(shí),也獲取到了。 那這樣,我們就可以通過Session會(huì)話對(duì)象,在同一個(gè)會(huì)話的多次請(qǐng)求之間來進(jìn)行數(shù)據(jù)共享了。

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):Session是存儲(chǔ)在服務(wù)端的,安全

  • 缺點(diǎn):

    • 服務(wù)器集群環(huán)境下無法直接使用Session

    • 移動(dòng)端APP(Android、IOS)中無法使用Cookie

    • 用戶可以自己禁用Cookie

    • Cookie不能跨域

是的,想必你們也發(fā)現(xiàn)了,cookie的缺點(diǎn),session也有,畢竟session就是基于cookie實(shí)現(xiàn)的。

下面我們開始本文目標(biāo):JWT

令牌

這里我們所提到的令牌,其實(shí)它就是一個(gè)用戶身份的標(biāo)識(shí),看似很高大上,很神秘,其實(shí)本質(zhì)就是一個(gè)字符串。想必很多90后都曾經(jīng)擁有過一個(gè)實(shí)體的QQ令牌,并且現(xiàn)在Steam也有登錄的令牌。實(shí)質(zhì)上他們的功能作用是一樣的。其實(shí)它就是一個(gè)用戶身份的標(biāo)識(shí),本質(zhì)就是一個(gè)字符串。

如果通過令牌技術(shù)來跟蹤會(huì)話,我們就可以在瀏覽器發(fā)起請(qǐng)求。在請(qǐng)求登錄接口的時(shí)候,如果登錄成功,我就可以生成一個(gè)令牌,令牌就是用戶的合法身份憑證。接下來我在響應(yīng)數(shù)據(jù)的時(shí)候,我就可以直接將令牌響應(yīng)給前端。

接下來我們?cè)谇岸顺绦虍?dāng)中接收到令牌之后,就需要將這個(gè)令牌存儲(chǔ)起來。這個(gè)存儲(chǔ)可以存儲(chǔ)在 cookie 當(dāng)中,也可以存儲(chǔ)在其他的存儲(chǔ)空間(比如:localStorage)當(dāng)中。

接下來,在后續(xù)的每一次請(qǐng)求當(dāng)中,都需要將令牌攜帶到服務(wù)端。攜帶到服務(wù)端之后,接下來我們就需要來校驗(yàn)令牌的有效性。如果令牌是有效的,就說明用戶已經(jīng)執(zhí)行了登錄操作,如果令牌是無效的,就說明用戶之前并未執(zhí)行登錄操作。

此時(shí),如果是在同一次會(huì)話的多次請(qǐng)求之間,我們想共享數(shù)據(jù),我們就可以將共享的數(shù)據(jù)存儲(chǔ)在令牌當(dāng)中就可以了。

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):

    • 支持PC端、移動(dòng)端

    • 解決集群環(huán)境下的認(rèn)證問題

    • 減輕服務(wù)器的存儲(chǔ)壓力(無需在服務(wù)器端存儲(chǔ))

  • 缺點(diǎn):需要自己實(shí)現(xiàn)(包括令牌的生成、令牌的傳遞、令牌的校驗(yàn))

針對(duì)于這三種方案,現(xiàn)在企業(yè)開發(fā)當(dāng)中使用的最多的就是第三種令牌技術(shù)進(jìn)行會(huì)話跟蹤。而前面的這兩種傳統(tǒng)的方案,現(xiàn)在企業(yè)項(xiàng)目開發(fā)當(dāng)中已經(jīng)很少使用了。所以在我們的課程當(dāng)中,我們也將會(huì)采用令牌技術(shù)來解決案例項(xiàng)目當(dāng)中的會(huì)話跟蹤問題。

JWT

JWT全稱:JSON Web Token (官網(wǎng):JSON Web Tokens - jwt.io

  • 定義了一種簡潔的、自包含的格式,用于在通信雙方以json數(shù)據(jù)格式安全的傳輸信息。由于數(shù)字簽名的存在,這些信息是可靠的。

    簡潔:是指jwt就是一個(gè)簡單的字符串??梢栽谡?qǐng)求參數(shù)或者是請(qǐng)求頭當(dāng)中直接傳遞。

    自包含:指的是jwt令牌,看似是一個(gè)隨機(jī)的字符串,但是我們是可以根據(jù)自身的需求在jwt令牌中存儲(chǔ)自定義的數(shù)據(jù)內(nèi)容。如:可以直接在jwt令牌中存儲(chǔ)用戶的相關(guān)信息。

    簡單來講,jwt就是將原始的json數(shù)據(jù)格式進(jìn)行了安全的封裝,這樣就可以直接基于jwt在通信雙方安全的進(jìn)行信息傳輸了。

JWT的組成: (JWT令牌由三個(gè)部分組成,三個(gè)部分之間使用英文的點(diǎn)來分割)

  • 第一部分:Header(頭), 記錄令牌類型、簽名算法等。 例如:{"alg":"HS256","type":"JWT"}

  • 第二部分:Payload(有效載荷),攜帶一些自定義信息、默認(rèn)信息等。 例如:{"id":"1","username":"Tom"}

  • 第三部分:Signature(簽名),防止Token被篡改、確保安全性。將header、payload,并加入指定秘鑰,通過指定簽名算法計(jì)算而來。

    簽名的目的就是為了防jwt令牌被篡改,而正是因?yàn)閖wt令牌最后一個(gè)部分?jǐn)?shù)字簽名的存在,所以整個(gè)jwt 令牌是非常安全可靠的。一旦jwt令牌當(dāng)中任何一個(gè)部分、任何一個(gè)字符被篡改了,整個(gè)令牌在校驗(yàn)的時(shí)候都會(huì)失敗,所以它是非常安全可靠的。

JWT是如何將原始的JSON格式數(shù)據(jù),轉(zhuǎn)變?yōu)樽址哪兀?/p>

其實(shí)在生成JWT令牌時(shí),會(huì)對(duì)JSON格式的數(shù)據(jù)進(jìn)行一次編碼:進(jìn)行base64編碼

Base64:是一種基于64個(gè)可打印的字符來表示二進(jìn)制數(shù)據(jù)的編碼方式。既然能編碼,那也就意味著也能解碼。所使用的64個(gè)字符分別是A到Z、a到z、 0- 9,一個(gè)加號(hào),一個(gè)斜杠,加起來就是64個(gè)字符。任何數(shù)據(jù)經(jīng)過base64編碼之后,最終就會(huì)通過這64個(gè)字符來表示。當(dāng)然還有一個(gè)符號(hào),那就是等號(hào)。等號(hào)它是一個(gè)補(bǔ)位的符號(hào)

需要注意的是Base64是編碼方式,而不是加密方式。

JWT令牌最典型的應(yīng)用場景就是登錄認(rèn)證:

1. 在瀏覽器發(fā)起請(qǐng)求來執(zhí)行登錄操作,此時(shí)會(huì)訪問登錄的接口,如果登錄成功之后,我們需要生成一個(gè)jwt令牌,將生成的 jwt令牌返回給前端。
2. 前端拿到j(luò)wt令牌之后,會(huì)將jwt令牌存儲(chǔ)起來。在后續(xù)的每一次請(qǐng)求中都會(huì)將jwt令牌攜帶到服務(wù)端。
3. 服務(wù)端統(tǒng)一攔截請(qǐng)求之后,先來判斷一下這次請(qǐng)求有沒有把令牌帶過來,如果沒有帶過來,直接拒絕訪問,如果帶過來了,還要校驗(yàn)一下令牌是否是有效。如果有效,就直接放行進(jìn)行請(qǐng)求的處理。

在JWT登錄認(rèn)證的場景中我們發(fā)現(xiàn),整個(gè)流程當(dāng)中涉及到兩步操作:

1. 在登錄成功之后,要生成令牌。
2. 每一次請(qǐng)求當(dāng)中,要接收令牌并對(duì)令牌進(jìn)行校驗(yàn)。

簡單介紹了JWT令牌以及JWT令牌的組成之后,接下來我們就來學(xué)習(xí)基于Java代碼如何生成和校驗(yàn)JWT令牌。

首先我們先來實(shí)現(xiàn)JWT令牌的生成。要想使用JWT令牌,需要先引入JWT的依賴:

<!-- JWT依賴-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

 接下來我們生成算法:

@Test
public void genJwt(){
    Map<String,Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("username","HongKongDoll");
    
    String jwt = Jwts.builder()
        .setClaims(claims) //自定義內(nèi)容(載荷)          
        .signWith(SignatureAlgorithm.HS256, "bug,start") //簽名算法        
        .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期   
        .compact();
    
    System.out.println(jwt);
}

走你:

這時(shí)我們使用utools上的插件進(jìn)行解碼(或者找任一在線解碼網(wǎng)站都可)

第一部分解析出來,看到JSON格式的原始數(shù)據(jù),所使用的簽名算法為HS256。

第二個(gè)部分是我們自定義的數(shù)據(jù),之前我們自定義的數(shù)據(jù)就是id,還有一個(gè)exp代表的是我們所設(shè)置的過期時(shí)間。

由于前兩個(gè)部分是base64編碼,所以是可以直接解碼出來。但最后一個(gè)部分并不是base64編碼,是經(jīng)過簽名算法計(jì)算出來的,所以最后一個(gè)部分是不會(huì)解析的。

實(shí)現(xiàn)了JWT令牌的生成,下面我們接著使用Java代碼來校驗(yàn)JWT令牌(解析生成的令牌):

 @Test
 public void parseJwt(){
     Claims claims = Jwts.parser()
                .setSigningKey("bug,start")//指定簽名密鑰(必須保證和生成令牌時(shí)使用相同的簽名密鑰)
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNzA0ODU1NTk5LCJ1c2VybmFtZSI6IkhvbmdLb25nRG9sbCJ9.JLg62R07Zr_IEZtaZ4oAQNkGoNIdGKrLbcy-OUCTTPU")
                .getBody();

        System.out.println(claims);
    }

走我:

令牌解析后,我們可以看到id和過期時(shí)間,如果在解析的過程當(dāng)中沒有報(bào)錯(cuò),就說明解析成功了。

接下來,為了驗(yàn)證JWT的可靠性,我們修改JWT中其中任一字母,重新進(jìn)行解析:

走他:

我只是把第一位的e換成了E,結(jié)果就報(bào)錯(cuò):JWT解析異常。說明解析JWT只要修改其中任一字符,就會(huì)解析失敗。

這時(shí)候又有一位未來首付要問了,那么還有其他的解析失敗因素嗎?當(dāng)然有啦,那就是過期時(shí)間,我們?cè)谏厦嬖O(shè)置了過期時(shí)間,那么我們現(xiàn)在把生成策略中過期時(shí)間換成1秒過期:

我們重新解析一下:

這次報(bào)的是JWT過期異常。

通過以上測(cè)試,我們?cè)谑褂肑WT令牌時(shí)需要注意:

  • JWT校驗(yàn)時(shí)使用的簽名秘鑰,必須和生成JWT令牌時(shí)使用的秘鑰是配套的。

  • 如果JWT令牌解析校驗(yàn)時(shí)報(bào)錯(cuò),則說明 JWT令牌被篡改 或 過期失效了,令牌非法。

接下來,我們進(jìn)入實(shí)戰(zhàn)部分:

JWT令牌的生成和校驗(yàn)的基本操作我們已經(jīng)學(xué)習(xí)完了,接下來我們就需要在案例當(dāng)中通過JWT令牌技術(shù)來跟蹤會(huì)話。具體的思路我們前面已經(jīng)分析過了,主要就是兩步操作:

  • 生成令牌

    在登錄成功之后來生成一個(gè)JWT令牌,并且把這個(gè)令牌直接返回給前端
  • 校驗(yàn)令牌

    攔截前端請(qǐng)求,從請(qǐng)求中獲取到令牌,對(duì)令牌進(jìn)行解析校驗(yàn)

那我們首先來完成:登錄成功之后生成JWT令牌,并且把令牌返回給前端。

 在controller同級(jí)下,建一個(gè)包,用來放我們的工具類,然后新建一個(gè)class:

/**
 * @Description JWT工具類
 * @Author QingNing
 * @Date 2024/1/9
 */
package com.ycg.vue.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    private static final String signKey = "bug,start";//簽名密鑰
    private static final Long expire = 3600000L; //有效時(shí)間

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分負(fù)載 payload 中存儲(chǔ)的內(nèi)容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)//自定義信息(有效載荷)
                .signWith(SignatureAlgorithm.HS256, signKey)//簽名算法(頭部)
                .setExpiration(new Date(System.currentTimeMillis() + expire))//過期時(shí)間
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分負(fù)載 payload 中存儲(chǔ)的內(nèi)容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)//指定簽名密鑰
                .parseClaimsJws(jwt)//指定令牌Token
                .getBody();
        return claims;
    }
}

 然后在登陸功能中添加JWT生成策略:

以下是本人的登陸代碼,僅做參考

 @ApiOperation(value = "用戶登錄")
    @PostMapping("/login")
    public result user(@RequestBody UserVo userVo){
        User user = userService.login(userVo);
        //非空判斷
        if(!Objects.isNull(user)){
            //生成
            Map<String , Object> claims = new HashMap<>();
            claims.put("id", user.getId());
            claims.put("username",user.getUsername());

            //使用JWT工具類,生成身份令牌
            String token = JwtUtils.generateJwt(claims);
            return result.success(token);
        }
        return result.error("用戶名或密碼錯(cuò)誤,請(qǐng)重新輸入");
    }

我們打開swagger進(jìn)行查看是否成功。

我們發(fā)現(xiàn),已經(jīng)返回了token,后續(xù)的每一次請(qǐng)求當(dāng)中,都會(huì)將這個(gè)令牌攜帶到服務(wù)端。 

此時(shí)我們只需要在前端的返回方法中,添加回調(diào)方法:

即可將jwt令牌存到請(qǐng)求頭中,在進(jìn)行其他操作時(shí)就會(huì)攜帶jwt令牌,直至本次會(huì)話結(jié)束。后續(xù)可以使用攔截器進(jìn)行判斷。

至此,我們就完成了JWT令牌的實(shí)現(xiàn)。

到此這篇關(guān)于JAVA后端實(shí)現(xiàn)JWT令牌的示例的文章就介紹到這了,更多相關(guān)JAVA JWT令牌內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配

    AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配

    這篇文章主要介紹了AndroidQ沙盒機(jī)制之分區(qū)存儲(chǔ)適配,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • JAVA代碼塊你了解嗎

    JAVA代碼塊你了解嗎

    這篇文章主要介紹了舉例說明Java中的代碼塊,包括靜態(tài)屬性和非靜態(tài)屬性以及構(gòu)造函數(shù)等相關(guān)的執(zhí)行先后,需要的朋友可以參考下
    2021-09-09
  • 一文詳解SpringBoot?Redis多數(shù)據(jù)源配置

    一文詳解SpringBoot?Redis多數(shù)據(jù)源配置

    Spring?Boot默認(rèn)只允許一種?Redis?連接池配置,且配置受限于?Lettuce?包,不夠靈活,所以本文將為大家介紹如何自定義Redis配置方案實(shí)現(xiàn)多數(shù)據(jù)源支持,需要的可以參考下
    2024-11-11
  • Java 位運(yùn)算符>>與>>>區(qū)別案例詳解

    Java 位運(yùn)算符>>與>>>區(qū)別案例詳解

    這篇文章主要介紹了Java 位運(yùn)算符>>與>>>區(qū)別案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java多線程join方法實(shí)例代碼

    Java多線程join方法實(shí)例代碼

    這篇文章主要介紹了Java多線程join方法實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 零基礎(chǔ)寫Java知乎爬蟲之抓取知乎答案

    零基礎(chǔ)寫Java知乎爬蟲之抓取知乎答案

    上篇文章我們已經(jīng)能把知乎的問題抓出來了,但是答案還木有抓出來。這一回合,我們就連著把答案也一起從網(wǎng)站中摳出來=。=
    2014-11-11
  • 使用自定義注解實(shí)現(xiàn)redisson分布式鎖

    使用自定義注解實(shí)現(xiàn)redisson分布式鎖

    這篇文章主要介紹了使用自定義注解實(shí)現(xiàn)redisson分布式鎖,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 最新評(píng)論