1. 程式人生 > >Json Web Token(JWT)

Json Web Token(JWT)

.json import form hid color 執行 加密方法 isa dep

Json web token (JWT),是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519)。該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。

組成

由句號分隔的三段base64串b1.b2.b3,如:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

  • header:頭部用於描述關於該JWT的最基本的信息,例如其類型以及簽名所用的算法等,為json格式。用base64轉成一個串b1。
  • paload:放入一些自定義信息,為json格式。用base64轉成一個串b2。jwt預放入了五個字段:
    • iss: 該JWT的簽發者
    • sub: 該JWT所面向的用戶
    • aud: 接收該JWT的一方
    • exp(expires): 什麽時候過期,這裏是一個Unix時間戳
    • iat(issued at): 在什麽時候簽發的
  • signature:用header中所聲明的加密方法(需要為之提供一個key)將 base64( header).base64(paload) 加密得到第三個base64串b3。

校驗原理

由於用base64,所以可以直接逆轉碼提取header、payload信息。服務端收到token後會根據header聲明的加密算法再計算下signature,若與token中的signature不同則當成未授權的token。

功能

(與傳統session或token的區別):

  • 適合用於向Web應用傳遞一些非敏感信息如userId、isAdmin等,不能包含密碼等敏感信息;
  • 本身具備失效判斷機制:根據串本身就能知道該token是否失效,而不用自己出來了;
  • 服務端不需要存儲token,而是分散給各個客戶端存儲,session機制則要。有利就有弊,jwt增加了計算開銷如加解密,但總的利大於弊。
  • 服務端能識別被篡改的token,所以只要token校驗通過,就可以把裏面封裝的信息當成可信的。

使用示例

依賴:

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

代碼:

技術分享圖片
 1 import java.security.Key;
 2 
 3 import io.jsonwebtoken.Claims;
 4 import io.jsonwebtoken.ExpiredJwtException;
 5 import io.jsonwebtoken.Jws;
 6 import io.jsonwebtoken.Jwts;
 7 import io.jsonwebtoken.MalformedJwtException;
 8 import io.jsonwebtoken.SignatureAlgorithm;
 9 import io.jsonwebtoken.SignatureException;
10 import io.jsonwebtoken.impl.crypto.MacProvider;
11 
12 public class JWTtest {
13 
14     public static void main(String[] args) {
15         // 生成jwt
16         Key key = MacProvider.generateKey();// 這裏是加密解密的key。
17         String compactJws = Jwts.builder()// 返回的字符串便是我們的jwt串了
18                 .setSubject("Joe")// 設置主題
19                 .claim("studentId", 2)// 添加自定義數據
20                 .signWith(SignatureAlgorithm.HS512, key)// 設置算法(必須)
21                 .compact();// 這個是全部設置完成後拼成jwt串的方法
22         System.out.println("the generated token is: " + compactJws);
23 
24         // 解析jwt
25         try {
26 
27             Jws<Claims> parseClaimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);// compactJws為jwt字符串
28             Claims body = parseClaimsJws.getBody();// 得到body後我們可以從body中獲取我們需要的信息
29             // 比如 獲取主題,當然,這是我們在生成jwt字符串的時候就已經存進來的
30             String subject = body.getSubject();
31             System.out.println("the subject is: " + subject);
32             System.out.println("the studentId is: " + body.get("studentId"));
33 
34             // OK, we can trust this JWT
35 
36         } catch (SignatureException | MalformedJwtException e) {
37             // TODO: handle exception
38             // don‘t trust the JWT!
39             // jwt 解析錯誤
40         } catch (ExpiredJwtException e) {
41             // TODO: handle exception
42             // jwt 已經過期,在設置jwt的時候如果設置了過期時間,這裏會自動判斷jwt是否已經過期,如果過期則會拋出這個異常,我們可以抓住這個異常並作相關處理。
43         }
44     }
45 }
View Code

參考資料

  • Json Web Token:http://blog.leapoahead.com/2015/09/06/understanding-jwt/
  • Json Web Token單點登錄:http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/

Json Web Token(JWT)