最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中JWT的使用的詳細教程

 更新時間:2023年02月09日 11:43:48   作者:ccx-lly  
JWT的本質(zhì)就是一個字符串,它是將用戶信息保存到一個Json字符串中,然后進行編碼后得到一個JWT token,并且這個JWT token帶有簽名信息,接收后可以校驗是否被篡改,所以可以用于在各方之間安全地將信息作為Json對象傳輸,本文介紹了Java中JWT的使用,需要的朋友可以參考下

JWT簡介

JWT全稱為Json Web Token

JWT的本質(zhì)就是一個字符串,它是將用戶信息保存到一個Json字符串中,然后進行編碼后得到一個JWT token,并且這個JWT token帶有簽名信息,接收后可以校驗是否被篡改,所以可以用于在各方之間安全地將信息作為Json對象傳輸。
JWT的認證流程如下:
1 首先,前端通過Web表單將自己的用戶名和密碼發(fā)送到后端的接口,這個過程一般是一個POST請求。建議的方式是通過SSL加密的傳輸(HTTPS),從而避免敏感信息被嗅探
2 后端核對用戶名和密碼成功后,將包含用戶信息的數(shù)據(jù)作為JWT的Payload,將其與JWT Header分別進行Base64編碼后拼接簽名,形成一個JWT Token,形成的JWT Token就是一個如同lll.zzz.xxx的字符串
3 后端將JWT Token字符串作為登錄成功的結(jié)果返回給前端。前端可以將返回的結(jié)果保存在瀏覽器中,退出登錄時刪除保存的JWT Token即可
4 前端在每次請求時將JWT Token放入HTTP請求頭中的Authorization屬性中(解決XSS和XSRF問題)
5 后端檢查前端傳過來的JWT Token,驗證其有效性,比如檢查簽名是否正確、是否過期、token的接收方是否是自己等等
6 驗證通過后,后端解析出JWT Token中包含的用戶信息,進行其他邏輯操作(一般是根據(jù)用戶信息得到權(quán)限等),返回結(jié)果

JWT結(jié)構(gòu)

JWT由3部分組成:標頭(header)、有效載荷(payLoad)、簽名(signature)。
在傳輸?shù)臅r候,會將JWT的3部分分別進行Base64編碼后用.連接形成最終傳輸?shù)淖址?/p>

Header

JWT頭是一個描述JWT元數(shù)據(jù)的JSON對象,alg屬性表示簽名使用的算法,默認為HMAC SHA256(寫為HS256);typ屬性表示令牌的類型,JWT令牌統(tǒng)一寫為JWT。最后,使用Base64 URL算法將上述JSON對象轉(zhuǎn)換為字符串保存

{
  "alg": "HS256",
  "typ": "JWT"
}

PayLoad

有效載荷部分,是JWT的主體內(nèi)容部分,也是一個JSON對象,包含需要傳遞的數(shù)據(jù)。 JWT指定七個默認字段供選擇

iss:發(fā)行人
exp:到期時間
sub:主題
aud:用戶
nbf:在此之前不可用
iat:發(fā)布時間
jti:JWT ID用于標識該JWT

除以上默認字段外,我們還可以自定義私有字段,一般會把包含用戶信息的數(shù)據(jù)放到payload中,如下

{
  "id": "123",
  "name": "cheng"
}

Signature

簽名哈希部分是對上面兩部分數(shù)據(jù)簽名,需要使用base64編碼后的header和payload數(shù)據(jù),通過指定的算法生成哈希,以確保數(shù)據(jù)不會被篡改。首先,需要指定一個密鑰(secret)。該密碼僅僅為保存在服務(wù)器中,并且不能向用戶公開。然后,使用header中指定的簽名算法(默認情況下為HMAC SHA256)根據(jù)以下公式生成簽名
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

在計算出簽名哈希后,JWT頭,有效載荷和簽名哈希的三個部分組合成一個字符串,每個部分用.分隔,就構(gòu)成整個JWT對象

注意JWT每部分的作用,在服務(wù)端接收到客戶端發(fā)送過來的JWT token之后:
header和payload可以直接利用base64解碼出原文,從header中獲取哈希簽名的算法,從payload中獲取有效數(shù)據(jù)
signature由于使用了不可逆的加密算法,無法解碼出原文,它的作用是校驗token有沒有被篡改。服務(wù)端獲取header中的加密算法之后,利用該算法加上secretKey對header、payload進行加密,比對加密后的數(shù)據(jù)和客戶端發(fā)送過來的是否一致。

為了完成簽名,除了用到header信息和payload信息外,還需要算法的密鑰,也就是secretKey。加密的算法一般有2類:

  • 對稱加密:secretKey指加密密鑰,可以生成簽名與驗簽
  • 非對稱加密:secretKey指私鑰,只用來生成簽名,不能用來驗簽(驗簽用的是公鑰)
    JWT的密鑰或者密鑰對,一般統(tǒng)一稱為JSON Web Key,也就是JWK
    到目前為止,jwt的簽名算法有三種:
  • HMAC【哈希消息驗證碼(對稱)】:HS256/HS384/HS512
  • RSASSA【RSA簽名算法(非對稱)】(RS256/RS384/RS512)
  • ECDSA【橢圓曲線數(shù)據(jù)簽名算法(非對稱)】(ES256/ES384/ES512)

Java中使用JWT

我這里用的是java-jwt

引入依賴

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

對稱簽名

生成JWT的Token

/**
     * 生成JWT token
     */
    @Test
    void generateToken(){
        //預(yù)設(shè)一個token過期時間
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR,1);//過期時間為1小時
        String token = JWT.create()
                .withHeader(new HashMap<>())//Header
                .withClaim("userId", 123)//PayLoad
                .withClaim("userName", "程")
                .withClaim("userId1", "456")
                .withExpiresAt(calendar.getTime())//過期時間
                .sign(Algorithm.HMAC256("12345"));//簽名用的密鑰secret
        System.out.println(token);
    }

利用base64解密工具來查看生成的JWT Token中header和payLoad的明文

解析JWT字符串

    /**
     * 解析jwt字符串
     */
    @Test
    void resolveToken(){
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWRJbnQiOjEyMywidXNlcklkU3RyaW5nIjoiNDU2IiwidXNlck5hbWUiOiLnqIsiLCJleHAiOjE2NzU5MTQzMDZ9.MNC-YCxt8C0t9SNbj3_XMRknkK3-PKBP5xX6_JLB8y8";
        //創(chuàng)建解析對象,使用的算法和secret要和創(chuàng)建token時保持一致
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("12345")).build();
        DecodedJWT decodedJWT = jwtVerifier.verify(token);
        System.out.println(decodedJWT.getPayload());//base64編碼的payLoad
        Claim userIdInt = decodedJWT.getClaim("userIdInt");
        Claim userIdString = decodedJWT.getClaim("userIdString");
        Claim userName = decodedJWT.getClaim("userName");
        System.out.println("userIdInt:"+userIdInt.asInt());
        System.out.println("userIdString:"+userIdString.asString());
        System.out.println("userName:"+userName.asString());
        System.out.println("過期時間:"+new LocalDateTime(decodedJWT.getExpiresAt()));
    }

如果我們設(shè)置的token時間短,比如設(shè)置為1秒

那么解析時為拋出如下異常

非對稱簽名

private static final String RSA_PRIVATE_KEY = "...";
private static final String RSA_PUBLIC_KEY = "...";

    /**
     * 生成token
     * @param payload token攜帶的信息
     * @return token字符串
     */
public static String getTokenRsa(Map<String,String> payload){
    // 指定token過期時間為7天
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, 7);

    JWTCreator.Builder builder = JWT.create();
    // 構(gòu)建payload
    payload.forEach((k,v) -> builder.withClaim(k,v));

    // 利用hutool創(chuàng)建RSA
    RSA rsa = new RSA(RSA_PRIVATE_KEY, null);
    // 獲取私鑰
    RSAPrivateKey privateKey = (RSAPrivateKey) rsa.getPrivateKey();
    // 簽名時傳入私鑰
    String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.RSA256(null, privateKey));
    return token;
}

    /**
     * 解析token
     * @param token token字符串
     * @return 解析后的token
     */
public static DecodedJWT decodeRsa(String token){
    // 利用hutool創(chuàng)建RSA
    RSA rsa = new RSA(null, RSA_PUBLIC_KEY);
    // 獲取RSA公鑰
    RSAPublicKey publicKey = (RSAPublicKey) rsa.getPublicKey();
    // 驗簽時傳入公鑰
    JWTVerifier jwtVerifier = JWT.require(Algorithm.RSA256(publicKey, null)).build();
    DecodedJWT decodedJWT = jwtVerifier.verify(token);
    return decodedJWT;
}

到此這篇關(guān)于Java中JWT的使用的文章就介紹到這了,更多相關(guān)Java中JWT使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用SpringBoot獲取resources文件路徑

    使用SpringBoot獲取resources文件路徑

    這篇文章主要介紹了使用SpringBoot獲取resources文件路徑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類

    三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類

    這篇文章主要介紹了三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • mybatis的大于小于號轉(zhuǎn)義符號一覽

    mybatis的大于小于號轉(zhuǎn)義符號一覽

    這篇文章主要介紹了mybatis的大于小于號轉(zhuǎn)義符號一覽,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • JPA save()方法將字段更新為null的解決方案

    JPA save()方法將字段更新為null的解決方案

    這篇文章主要介紹了JPA save()方法將字段更新為null的解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Java?CompletableFuture實現(xiàn)多線程異步編排

    Java?CompletableFuture實現(xiàn)多線程異步編排

    這篇文章主要為大家介紹了Java?CompletableFuture實現(xiàn)多線程異步編排,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Java實現(xiàn)餐廳點餐系統(tǒng)的實例代碼

    Java實現(xiàn)餐廳點餐系統(tǒng)的實例代碼

    這篇文章主要介紹了Java實現(xiàn)餐廳點餐系統(tǒng),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • gradle構(gòu)建工具和java不兼容錯誤的解決方案

    gradle構(gòu)建工具和java不兼容錯誤的解決方案

    這篇文章主要介紹了如何解決AS中Gradle和Java版本不兼容的問題,主要解決方案包括升級Gradle版本或降級Java版本,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • Java讀取文件的幾種方式詳細總結(jié)

    Java讀取文件的幾種方式詳細總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java讀取文件的幾種方式,文中通過代碼示例將幾種方式介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友可以參考下
    2023-08-08
  • Java實現(xiàn)簡單的飛機大戰(zhàn)游戲(控制主飛機篇)

    Java實現(xiàn)簡單的飛機大戰(zhàn)游戲(控制主飛機篇)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)簡單的飛機大戰(zhàn)游戲,控制主飛機,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java 制作驗證碼并進行驗證實例詳解

    java 制作驗證碼并進行驗證實例詳解

    這篇文章主要介紹了java 制作驗證碼并進行驗證實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04

最新評論

合山市| 锡林浩特市| 平舆县| 宜州市| 韶关市| 清新县| 汉川市| 利川市| 色达县| 肃北| 文山县| 佛教| 龙岩市| 中江县| 金阳县| 天柱县| 河津市| 西城区| 萝北县| 温泉县| 侯马市| 大荔县| 珲春市| 辽中县| 栖霞市| 苏尼特右旗| 海口市| 洪湖市| 丰台区| 镇远县| 安图县| 嘉禾县| 库伦旗| 民和| 佛冈县| 庄河市| 衡南县| 印江| 章丘市| 长海县| 四平市|