1.JWT簡介
JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。
詳細介紹:https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=pc
2.前提
2.1所需jar包
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.1</version>
</dependency>
2.2可能出現問題
java.lang.NoClassDefFoundError:com/fasterxml/jackson/databind/ObjectMapper
此信息爲spring和jackson相關版本不兼容,將本地jsckson版本升到2.7.5以上或者更高即可(可與舊版本同時存在)
相關依賴如下(我只升級了jackson-core和jackson-databind就可以了):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.4</version>
</dependency>
Spring爲4.3.2兼容jackson版本爲2.7.5和更高版本,相關依賴如下:
3.JWT在JAVA中應用方案
以下爲JWT測試類,有詳細加解密代碼。
package cn.bxn.test;
import java.util.Date;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.interfaces.DecodedJWT;
public class JWTTest {
/**
* 生成加密後的token
* @param username 用戶名
* @param name 姓名
* @return 加密後的token
*/
public static String getToken(String username, String category) {
String token = null;
try {
Date expiresAt = new Date(System.currentTimeMillis() + 24L * 60L * 3600L * 1000L);
token = JWT.create().withIssuer("auth0").withClaim("username", username).withClaim("category", category)
.withExpiresAt(expiresAt)
// 使用了HMAC256加密算法。
// mysecret是用來加密數字簽名的密鑰。
.sign(Algorithm.HMAC256("qingningtest20191224"));
} catch (JWTCreationException exception) {
// Invalid Signing configuration / Couldn't convert Claims.
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return token;
}
/**
* 解密
* @author 張超
*
*/
/**
* 先驗證token是否被僞造,然後解碼token。
* @param token 字符串token
* @return 解密後的DecodedJWT對象,可以讀取token中的數據。
*/
public static DecodedJWT deToken(final String token) {
DecodedJWT jwt = null;
try {
// 使用了HMAC256加密算法。
// mysecret是用來加密數字簽名的密鑰。
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("qingningtest20191224")).withIssuer("auth0").build();// Reusable
// verifier
// instance
jwt = verifier.verify(token);
} catch (JWTVerificationException exception) {
// Invalid signature/claims
exception.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jwt;
}
public static void main(String[] args) {
// 生成token
String token = JWTTest.getToken("888888", "4");
// 打印token
System.out.println("token: " + token);
// 解密token
DecodedJWT jwt = JWTTest.deToken(token);
System.out.println("username: " + jwt.getClaim("username").asString());
System.out.println("category: " + jwt.getClaim("category").asString());
System.out.println("過期時間: " + jwt.getExpiresAt());
}
}