如何使用jwt生成token


jwt應該如何使用呢?

下面來寫一個最簡單的jwt的使用demo

1. 引入依賴包:

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

2. 加密解密方法

public static void main(String[] args) {
        // 過期時間
        final Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, 1000);
        
        // 以abc為密鑰進行hmac256方法加密,保存 a,b兩個屬性
        final String token = JWT.create().withHeader(new HashMap<>())
                .withClaim("a", "ccc")
                .withClaim("b", JSONObject.toJSON(Arrays.asList("a", "b", "c")).toString())
                .withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256("abc"));
        System.out.println("token = " + token);

        // 解密
        JWTVerifier build = JWT.require(Algorithm.HMAC256("abc")).build();
        final DecodedJWT verify = build.verify(token);
        // 取出a
        final Claim a = verify.getClaim("a");
        System.out.println("a = " + a);
        System.out.println("a.asString() = " + a.asString());

        // 取出b
        final Claim b = verify.getClaim("b");
        System.out.println("b = " + b);
        System.out.println("b.asArray(List.class) = " + b.asString());

        // 取出過期時間
        final Date expiresAt = verify.getExpiresAt();
        System.out.println("expiresAt = " + expiresAt.toLocaleString());

    }

 

在生產環境中,一般jwt會保存用戶的名字和角色權限等信息。可以將token 寫到cookie里,每次前端訪問后台時,可以在攔截器或者過濾器取到token, 然后解密,先判斷是否過期,過期就拋異常阻止其訪問。然后取出信息保存到threadLocal里,方便以后調用這些信息,當后台訪問完成后,從thredLocal刪除此用戶信息。

3. 如何使用

登陸返回JWT, 客戶端瀏覽器拿到這個 JWT 字符串后,存儲到 cookie 或者 瀏覽器的 LocalStorage 中。再次發送請求,比如請求用戶設置頁面的時候,在 HTTP 請求頭中加入 JWT 字符串,或者直接放到請求主體中。

登錄過后給前端進行返回JWT並設置了過期時間30分鍾,后端接收請求的時候獲取請求頭出來進行jwt解析判斷過期時間是否小於10分鍾,如果小於10分鍾就生成新的 jwt 在responseHearde進行返回即可,前端每次都檢查responseHearde是否有jwt, 如果有,則替換localStorage 中的jwt .

 

 

 

 

 

 

jwt 結構解析

JWT由3部分組成:標頭(Header)、有效載荷(Payload)和簽名(Signature)

Header

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

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

Payload

是JWT的主體內容部分,也是一個JSON對象,包含需要傳遞的數據。 JWT指定七個默認字段供選擇

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

 這些預定義的字段並不要求強制使用。除以上默認字段外,我們還可以自定義私有字段,一般會把包含用戶信息的數據放到payload中

{ "sub": "1234567890", "name": "Helen", "admin": true ,roles:["admin","comsumer"]}

Signature

簽名哈希部分是對上面兩部分數據簽名,需要使用base64編碼后的header和payload數據,通過指定的算法生成哈希,以確保數據不會被篡改。首先,需要指定一個密鑰(secret)。該密碼僅僅為保存在服務器中,並且不能向用戶公開。

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

注意JWT每部分的作用,在服務端接收到客戶端發送過來的JWT token之后:

header和payload可以直接利用base64解碼出原文,從header中獲取哈希簽名的算法,從payload中獲取有效數據
signature由於使用了不可逆的加密算法,無法解碼出原文,它的作用是校驗token有沒有被篡改。服務端獲取header中的加密算法之后,利用該算法加上secretKey對header、payload進行加密,比對加密后的數據和客戶端發送過來的是否一致。注意secretKey只能保存在服務端,而且對於不同的加密算法其含義有所不同,一般對於MD5類型的摘要加密算法,secretKey實際上代表的是鹽值 

 

JWT 有效期內可以

JWT 有個問題,那就是一旦頒發一個 JWT 令牌,服務端就沒辦法廢棄掉它,除非等到它自身過期。有很多應用默認只允許最新登錄的一個客戶端正常使用,不允許多端登錄,JWT 就沒辦法做到,因為頒發了新令牌,但是老的令牌在過期前仍然可用。這種情況下,就需要服務端增加相應的邏輯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM