JWT在Java和Android中的使用

转载请注明出处:https://blog.csdn.net/mythmayor/article/details/81221642

一、JWT简介

JWT即JSON Web Token。JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息。 此信息可以通过数字签名进行验证和信任。 JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

虽然JWT可以加密以在各方之间提供保密,但我们将专注于签名令牌。 签名令牌可以验证其中包含的声明的完整性,而加密令牌则隐藏其他方的声明。 当使用公钥/私钥对签署令牌时,签名还证明只有持有私钥的一方是签署私钥的一方。

可前往 https://jwt.io/ 进行JWT的学习和使用

二、JWT在Java中的使用

首先我们要在https://jwt.io/主页上找到Java项目的入口,我在这里选择的是"maven: com.auth0 / java-jwt / 3.3.0",点击该项右下角的"View Repo"按钮即可跳转到项目Github主页进行导入。我在这里直接将导入步骤写下来,该版本为写文章时的最新版本。
Maven


    com.auth0
    java-jwt
    3.4.0

Gradle

compile 'com.auth0:java-jwt:3.4.0'
1.JWT生成
public String JWTGenerate(String key, String secret, String jwtSecret) {
    Map headers = new HashMap();
    headers.put("alg", "HS256");
    headers.put("typ", "JWT");
    String builder = JWT.create().withHeader(hearMap).withClaim("key", key).withClaim("secret", secret).sign(Algorithm.HMAC256(jwtSecret));
    return builder;
}
2.JWT解码
public void JWTDecode(String token) {
	try {
	    DecodedJWT jwt = JWT.decode(token);
        /**
         * Header Claims
         */
        //Returns the Algorithm value or null if it's not defined in the Header.
        String algorithm = jwt.getAlgorithm();
        //Returns the Type value or null if it's not defined in the Header.
        String type = jwt.getType();
        //Returns the Content Type value or null if it's not defined in the Header.
        String contentType = jwt.getContentType();
        //Returns the Key Id value or null if it's not defined in the Header.
        String keyId = jwt.getKeyId();
        //Private Claims
        Claim claim = jwt.getHeaderClaim("owner");
        /**
         * Payload Claims
         */
        //Returns the Issuer value or null if it's not defined in the Payload.
        String issuer = jwt.getIssuer();
        //Returns the Subject value or null if it's not defined in the Payload.
        String subject = jwt.getSubject();
        //Returns the Audience value or null if it's not defined in the Payload.
        List audience = jwt.getAudience();
        //Returns the Expiration Time value or null if it's not defined in the Payload.
        Date expiresAt = jwt.getExpiresAt();
        //Returns the Not Before value or null if it's not defined in the Payload.
        Date notBefore = jwt.getNotBefore();
        //Returns the Issued At value or null if it's not defined in the Payload.
        Date issuedAt = jwt.getIssuedAt();
        //Returns the JWT ID value or null if it's not defined in the Payload.
        String id = jwt.getId();
        //Private Claims
        Claim claim2 = jwt.getClaim("isAdmin");
	} catch (JWTDecodeException exception){
	    //Invalid token
	}
}

三、JWT在Android中的使用

最初我在安卓中也使用的上面的Java库,但发现在使用org.apache.commons.codec.binary.Base64时会与Android系统中的包出现冲突,自己尝试封装了一下并改了包名,可以成功调用,但这显然不是最好的方案。所以我在这里使用到另外一个库。我们在https://jwt.io/主页上找到Java项目的入口,我在这里选择的是"maven: io.jsonwebtoken / jjwt / 0.9.0",点击该项右下角的"View Repo"按钮即可跳转到项目Github主页进行导入。下面简单说明一下依赖库的方式。
Maven:


    io.jsonwebtoken
    jjwt
    0.9.1

Gradle:

dependencies {
    compile 'io.jsonwebtoken:jjwt:0.9.1'
}
1.JWT生成
public String JWTGenerate() {
    Map map = new HashMap<>();
    map.put("claim1", "claim1value");
    map.put("claim2", "claim2value");
    String key = Base64.encodeToString("secret".getBytes(), 0);
    //Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
    Date exp = new Date(System.currentTimeMillis() + 60 * 1000);//过期时间
    String compactJws = Jwts.builder().addClaims(map).setHeaderParam("typ", "JWT")
            .signWith(SignatureAlgorithm.HS256, key).setExpiration(exp).compact();
    try {
        Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);
        //OK, we can trust this JWT
    } catch (SignatureException e) {//don't trust the JWT!
        e.printStackTrace();
    } catch (ExpiredJwtException e) {//The key is expiration
        e.printStackTrace();
    }
    return compactJws;
}
2.JWT解码

先看一下使用上面的"jjwt"库如何进行解码操作:

public void JWTParse(String jwt) {
	String key = Base64.encodeToString("secret".getBytes(), 0);
    //Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
    //在解析的时候一定要传key进去,否则无法通过key的认证
    Jwt parse = Jwts.parser().setSigningKey(key).parse(jwt);
    Header header = parse.getHeader();
    Map map = (Map) parse.getBody();
    String param = (String) map.get("param");
}

另外还可以使用其它的库,可前往 https://github.com/auth0/JWTDecode.Android 进行学习和使用,当然,你也可以用上面提到的Java库来进行解码。
添加依赖:

compile 'com.auth0.android:jwtdecode:1.1.1'

使用:

String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
JWT jwt = new JWT(token);
/**
  * Registered Claims
  */
//Returns the Issuer value or null if it's not defined.
String issuer = jwt.getIssuer();
//Returns the Subject value or null if it's not defined.
String subject = jwt.getSubject();
//Returns the Audience value or an empty list if it's not defined.
List audience = jwt.getAudience();
//Returns the Expiration Time value or null if it's not defined.
Date expiresAt = jwt.getExpiresAt();
//Returns the Not Before value or null if it's not defined.
Date notBefore = jwt.getNotBefore();
//Returns the Issued At value or null if it's not defined.
Date issuedAt = jwt.getIssuedAt();
//Returns the JWT ID value or null if it's not defined.
String id = jwt.getId();
//Time Validation
boolean isExpired = jwt.isExpired(10); // 10 seconds leeway

/**
  * Private Claims
  */
Claim claim = jwt.getClaim("isAdmin");

四、遇到的问题及其处理方案

在AndroidStudio编译的时候会遇到这样一个问题:
这里写图片描述
解决方案为:
在Module的build.gradle中的android{}中添加下面代码:

packagingOptions {
    exclude 'META-INF/LICENSE'
}

哪个文件报错,就把哪个文件exclude出去。

你可能感兴趣的:(Android,Java)