相关资料网络上非常多,可以自行搜索,简单点说JWT就是一种网络身份认证和信息交换格式。
结构
- Header 头部信息,主要声明了JWT的签名算法等信息
- Payload 载荷信息,主要承载了各种声明并传递明文数据
- Signature 签名,拥有该部分的JWT被称为JWS,也就是签了名的JWS,用于校验数据
整体结构
header.payload.signature
方法:通过JWT实现链式创建JWT对象或JWT字符串
// 1.头部和载荷各自base64加密后用.连接起来,然后就形成了xxx.xx的前两段token。
// 2.最后一段token的形成是,前两段加入一个密匙用HS256算法或者其他算法加密形成。
// 最主要的目的:服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次签名,
// 如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,
// 那么就说明这个Token的内容被别人动过的,我们应该拒绝这个Token,返回一个HTTP 401 Unauthorized响应。
签名:可以使用签名工具,就是在第三段数字那里使用
对称签名
- HS256(HmacSHA256)
- HS384(HmacSHA384)
- HS512(HmacSHA512)
非对称签名
- RS256(SHA256withRSA)
- RS384(SHA384withRSA)
- RS512(SHA512withRSA)
- ES256(SHA256withECDSA)
- ES384(SHA384withECDSA)
- ES512(SHA512withECDSA)
依赖于BounyCastle的算法
- PS256(SHA256WithRSA/PSS)
- PS384(SHA384WithRSA/PSS)
- PS512(SHA512WithRSA/PSS)
//使用的hutool工具
@GetMapping("/in")
public String login(User user){
// 创建jwt内 的部分,uid 唯一标识,expire_time 过期时间
Map<String, Object> map = new HashMap<String, Object>() {
private static final long serialVersionUID = 1L;
{
put("uid", Integer.parseInt("123"));
put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15);
}
};
// 生成token,加入 token的第三段签名,
String token = JWTUtil.createToken(map, "1234".getBytes());
// 使用对称签名 HS256(HmacSHA256)
//final JWTSigner signer = JWTSignerUtil.hs256("123456".getBytes());
//JWT jwt = JWT.create().setSigner(signer);
return token;
}
@GetMapping("/loginIn")
public boolean loginIn(String token, HttpServletRequest request){
// String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." +
// "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." +
// "U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";
// 获取请求头中内容
String authorization = request.getHeader("Authorization");
// JWT解析
final JWT jwt = JWTUtil.parseToken(authorization);
jwt.getHeader(JWTHeader.TYPE);
jwt.getPayload("sub");
// JWT验证
boolean verify = JWTUtil.verify(authorization, "1234".getBytes());
return verify;
}