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());
}
}