天天看點

Android JWT 簡單使用

一、什麼是JWT?

JWT 的定義:

JWT的作用:

1、JWT可以了解為一串通過特定算法生成的字元串,在API的請求中,将這段字元串放入請求參數中。API Server通過判斷這段字元串是合法的還是僞造的,來确定這次API請求是否有效。通過該安全措施,将確定即使API被暴露,沒有生成JWT字元串的算法,也沒有辦法成功調用API。

2、JWT字元串分為兩個部分(官方的說法是分為3個部分),分别是‘未加密部分’和‘加密部分’。而‘加密部分’的内容實際上是‘未加密部分’加密得到的。API Server檢查JWT字元串是否有效的第一步是将‘加密部分’解密然後與‘未加密部分’進行比較,檢視是否内容一緻。如果内容不一緻,則說明該JWT字元串是僞造的。

3、JWT字元串中包括一個‘過期時間’的字段,當API Server擷取到JWT字元串後,可以通過檢查該字段與目前時間相比,是否已經處于過期的狀态。如果‘過期時間’字段早于目前時間,則說明這次API請求是無效的。

4、你也可以在JWT字段種加入自定義的字段。然後在API Server擷取到JWT字段後,通過這些自定義的字段判斷是不是符合具體的業務邏輯,進而判斷這次請求是不是有效。

二、JWT 基本使用步驟

1、 構造okHttp 請求

OkHttpClient mOkHttpClient = new OkHttpClient();
Request request = createBuilder().url(url) .post(builder.build()) .build();
mOkHttpClient.newCall(request).enqueue(new Callback(){});
           

2、在Request 的Header 中增加jwt 相關資訊,可以作為服務端對用戶端的安全校驗、身份校驗、權限校驗等

private static Builder createBuilder() {
    return (new Builder()).addHeader("Authorization", "Bearer " + generateJwt());
}
           

3、生成 JWT 字元串

static String generateJwt() {
    Date var0 = new Date();
    Long var1 = Long.valueOf(var0.getTime());
    Date var2 = new Date(var1.longValue() + L);
    HashMap var3 = new HashMap();
    var3.put("typ", "JWT");
    var3.put("alg", "HS256");
    String var4 = "";

    try {
        var4 = Jwts.builder().
setHeader(var3).
setIssuer(sAuthOctoKey).    //請求的發起者;
setIssuedAt(var0).          //請求的發起時間;
setExpiration(var2).        //expTime是過期時間,目前時間+200秒;
signWith(SignatureAlgorithm.HS256, Base64.encode(sAuthSecret.getBytes("UTF-8"))).   //兩個參數,一個是加密算法,一個秘鑰;SECRET_KEY是加密算法對應的密鑰,這裡使用額是HS256加密算法;
.claim("key","vaule")               //該方法是在JWT中加入值為vaule 的 key 自定義字段;
compact();
    } catch (Exception var6) {
        Log.e("HttpRequest", "octo generate error...", var6);
    }

    return var4;
}
           

4、服務端判斷JWT是否有效

public boolean isJwtValid(String jwt) {
  try {
  // 解析JWT字元串中的資料,并進行最基礎的驗證
  Claims claims = Jwts.parser()
  .setSigningKey(SECRET_KEY)  //SECRET_KEY是加密算法對應的密鑰,jjwt可以自動判斷機密算法;
  .parseClaimsJws(jwt)   //jwt是用戶端生成的JWT字元串;
  .getBody();
  String vaule = claims.get("key", String.class);   //擷取自定義字段key;

  // 判斷自定義字段是否正确
  if ("vaule".equals(vaule)) {
  return true;
  } else {
  return false;
  }
  }
  //在解析JWT字元串時,如果密鑰不正确,将會解析失敗,抛出SignatureException異常,說明該JWT字元串是僞造的;
  //在解析JWT字元串時,如果‘過期時間字段’已經早于目前時間,将會抛出ExpiredJwtException異常,說明本次請求已經失效;
  catch (SignatureException|ExpiredJwtException e) {
  return false;
  }
}
           

三、對 compact() 方法的探究

io.jsonwebtoken.JwtBuilder
String compact()
Actually builds the JWT and serializes it to a compact, URL-safe string according to the JWT Compact Serialization rules.
Returns:
A compact URL-safe JWT string.
           

四、其他

JWT在一定程度上,保護了API的安全。但是其本身還是存在一定的缺陷的。比如說,一定JWT的加密密鑰一旦被洩露,那麼黑客就可以生成JWT字元串了,是以保護好JWT加密密鑰非常重要。