JWT token令牌使用
一,什么是JWT?
JWT简称 json web token, 也就是通过JSON形式作为Web应用中的令牌,用于各方之间安全地将信息作为JSON格式进行传输。在传输过程中可以完成数据的加密,签名等相关处理。
二,JWT能做什么?
1,授权
当用户登录后,后续请求将包括JWT(可以放置于请求头或者cookies),从而允许用户进行相关的接口调用操作资源。单点登录也是常用的JWT控制手段之一(唯一用户同一时间只能有唯一合法的JWT认证token)
2,信息传输
你可以将你需要传递的信息加密封装到 JWT token中使用,当接收方收到token解密后可以获取token中传递的附属信息(如:用户角色,权限等)。由于签名是使用标头和有效负载计算的,因此我们还可以验证内容是否被篡改。
三,认证流程
1,前端将自己的用户名密码发到后端接口,一般是POST请求+HTTPS的SSL加密传输。
2,后端核对用户名,密码成功后,将用户的信息作为JWT 的payload,将其与头部分别进行Base64编码拼接后签名,生成一个JWT token(xxx.yyy.zzz的字符串)
3,后端将JWT字符串作为登录成功的结果返回给前端,前端将返回结果保存在localStorage或sessionStorage上。退出登录时删除保存的JWT即可。
4,前端在后续每次请求时将JWT放到HTTPS的Header中,进行后续的访问。
5,后端在后续接口的调用中检查JWT的有效性和时效性。
6,验证通过,进行操作。
四,JWT的结构
token string ==》 header.payload.singnature JWT token字符串 标头 有效负载 签名 Header 标头通常由两部分组成: 令牌的类型和所使用的签名算法(HMAC, SHA256或RSA),使用Base64编码组成JWT的第一部分。 Payload 开发人员设置的存储用户信息的负载(一般为用户所拥有的角色,权限等信息,不要放敏感信息,如密码等)使用Base64编码组成JWT的第二部分。 Singature 前面两部分都是使用Base64进行编码,可以解密知道里面的信息,签名需要使用编码后的header和payload以及一个密钥,然后用header中指定的签名算法进行签名。 如: HMACSHA256(base64UrlEncode(header)+ "." + base64UrlEncode(payload), secret); 最后一步的签名是为了安全,防止内容被篡改。
五,简单使用JWT
1,引入依赖
<!-- 引入JWT-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2, 生成JWT token
String sign = "adjuqbnvbnqkjnmweijn2154185q1aS'd.q";
HashMap<String, Object> header = new HashMap<>();
//1, 生成JWTtoken
public String generateJWT() {
header.put("typ", "JWT");
String token = JWT.create().withHeader(header) // header这步可以省略
.withClaim("name", "张三") // 设置有效负载
.withClaim("age", 15)
.sign(Algorithm.HMAC256(sign));
System.out.println(token);
return token;
}
生成如下:
3,解析token
public void parsingJWT(String token) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
DecodedJWT jwt = JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
System.out.println(jwt.getPayload());
System.out.println(jwt.getClaim("name").asString());
System.out.println(format.format(jwt.getExpiresAt().getTime()));
}
// 执行
public static void main(String[] args) {
JWTTest jwtTest = new JWTTest();
String token = jwtTest.generateJWT();
jwtTest.parsingJWT(token);
}
结果如下:
3,验证token是否有效或者是否过期
public Boolean tokenIsExpires(String token) {
try {
JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
return true;
} catch (Exception e) {
return false;
}
}
测试
public static void main(String[] args) throws InterruptedException {
JWTTest jwtTest = new JWTTest();
String token = jwtTest.generateJWT();
jwtTest.parsingJWT(token);
TimeUnit.SECONDS.sleep(6);
Boolean isExpires = jwtTest.tokenIsExpires(token);
if (isExpires) {
System.out.println("当前token还没过期");
} else {
System.out.println("当前token已经过期了");
}
}
结果