原理
JWT的原理是服务端认证之后,生成一个json对象回传用户。这个json对象包含一定的用户信息,为了防止数据被篡改,json中包含的签名,签名的秘钥放在服务器上。
数据结构
实际回传给用户的是这样的字符串:
eyJhbGciOiJIUzI1NiJ9.eyJhcGlOYW1lIjoidGVzdCIsImFwcE5hbWUiOiJ0ZXN0IiwiaXNzIjoiRkhaWiIsIm5hbWUiOiJhZG1pbiIsImV4cCI6MTU1MDU2NTU0N30.0BhdIFir-aJ_TJk_b5rDlMKOLxfrRx07d5n6nSGHEJU
中间的“. ”是分割符,JWT实际上由三部分组成,分别是header,playload,VERIFY SIGNATURE
header中存放描述JWT的元数据,如algorithm(加密算法):
{
"alg": "HS256"
}
playload中存放自定义的数据(用户信息等):
{
"apiName": "test",
"appName": "test",
"iss": "FHZZ",
"name": "admin",
"exp": 1550565547
}
VERIFY SIGNATURE中存放数据签名
JWT的使用
- 加入dependency:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.1.0</version>
</dependency>
- 生成token的方法:
public static String getToken(Map<String,String> claims){
try {
Algorithm algorithm=Algorithm.HMAC256(SECRET);
JWTCreator.Builder builder = JWT.create().withIssuer(ISSUER).withExpiresAt(DateUtils.addDays(new Date(), 1));
claims.forEach((k,v) -> builder.withClaim(k, v));
return builder.sign(algorithm).toString();
}catch (IllegalArgumentException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
参数claims为要写入到playload中的数据
- 验证token
public static Map<String, String> verifyToken(String token) {
Algorithm algorithm = null;
try {
algorithm = Algorithm.HMAC256(SECRET);
} catch (IllegalArgumentException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
DecodedJWT jwt = verifier.verify(token);
Map<String, Claim> map = jwt.getClaims();
Map<String, String> resultMap = Maps.newHashMap();
map.forEach((k,v) -> resultMap.put(k, v.asString()));
return resultMap;
}
验证成功会将playload中的数据以map的形式返回,验证失败会抛出异常,在程序中try、catch捕获即可