介绍
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.(摘自官网https://jwt.io/)
JWT.IO allows you to decode, verify and generate JWT.
jwt能做什么?
授权
一旦用户登陆。后续请求包括jwt,从而允许用户访问该令牌允许的路由、服务和资源,单点登录是当今广泛使用jwt的一项功能。
信息交换
jwt是各方之间安全传输信息的好方法,因为可以对jwt进行签名。
jwt认证
jwt结构
- header
- payload
- signature
header.payload.signature
header
由两个部分组成,令牌的类型和使用的签名算法,例如SHA256或RSA,它会使用base64编码组成JWT结构的一部分。
payload
有效负载,其中包含声明,声明是有关实体(通常是用户信息)和其他数据的生命,同样使用base64编码组成jwt第二部分。
signature
前面两部分都是使用base64进行编码的,即前端可以解开知道里面的信息,signature需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法(HS256)进行签名,签名的作用是保证JWT没有被修改过。
helloword
生成jwt
@Test
public void test(){
Map<String,Object> map = new HashMap<>();
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND,600);
String token = JWT.create()
.withExpiresAt(instance.getTime())//过期时间
.withHeader(map) //header
.withClaim("userId",123456)
.withClaim("username", "wenjie")//payload
.sign(Algorithm.HMAC256("wj@top"));//signature
System.out.println(token);
}
验证:
@Test
public void test2(){
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("wj@top")).build();
DecodedJWT decodedJWT = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDExMTkzNzYsInVzZXJJZCI6MTIzNDU2LCJ1c2VybmFtZSI6IndlbmppZSJ9.dq7uGUQWnN9C8bte-b-LkLU3cq-MEAJkWLnruS4MRbQ");
System.out.println(decodedJWT.getClaim("username").asString());
System.out.println(decodedJWT.getClaim("userId").asInt());
System.out.println(decodedJWT.getExpiresAt());
}
输出结果:
jwt工具类
package com.wj.jwt.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Map;
public class JwtUtils {
private static final String INFO = "wj@top";
/**
* 获取token
* @return
*/
public static String getToken(Map<String,String> map){
JWTCreator.Builder builder = JWT.create();
map.forEach(builder::withClaim);
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE,30);
builder.withExpiresAt(instance.getTime());
return builder.sign(Algorithm.HMAC256(INFO));
}
/**
* 验证合法性
* @param token
* @return
*/
public static boolean verify(String token){
try {
JWT.require(Algorithm.HMAC256(INFO)).build().verify(token);
return true;
}catch (Exception e){
//这里可以针对不同的异常,处理不同的逻辑
return false;
}
}
/**
* 获取token信息
* @param token
* @return
*/
public DecodedJWT getToken(String token){
return JWT.require(Algorithm.HMAC256(INFO)).build().verify(token);
}
}
相关异常
/**
* Perform the verification against the given Token, using any previous configured options.
*
* @param token to verify.
* @return a verified and decoded JWT.
* @throws AlgorithmMismatchException if the algorithm stated in the token's header it's not equal to the one defined in the {@link JWTVerifier}.
* @throws SignatureVerificationException if the signature is invalid.
* @throws TokenExpiredException if the token has expired.
* @throws InvalidClaimException if a claim contained a different value than the expected one.
*/
public DecodedJWT verify(String token) throws JWTVerificationException {
DecodedJWT jwt = JWT.decode(token);
verifyAlgorithm(jwt, algorithm);
algorithm.verify(jwt);
verifyClaims(jwt, claims);
return jwt;
}
AlgorithmMismatchException:算法不匹配异常
SignatureVerificationException:签名不一致异常
TokenExpiredException:token过期异常
InvalidClaimException:无效payload异常