JSON Web Token是一个开源的、遵循RFC 7519工业标准的方法,用于以JSON对象的方式,安全的表示服务器端、客户端双方之间的信息传输。JWT官网地址为:jwt.io/。
JWTs作为一种凭证,可以授予资源的访问权限。JWT并不会存储令牌本身,并且所有的验证和调试操作都在客户端完成。
JWT加密算法
JWT提供了如下图所示的、对于令牌的加密/解密算法,通过这种加密/解密算法,可以以不同的方式对用户的信息进行编码/解码操作。
编码&解码
如下图所示,以SH256算法,将以上用户信息进行编码,得到左侧部分的Token令牌,这个令牌将被从Java服务器端发送到浏览器客户端;对于持有左侧(经SH256算法编码的)Token令牌的客户端,当它在向服务器端发起请求时,Java后端就可以通过相同的SH256算法,将其解码为原始的用户信息。这就是利用JWT算法进行编码和解码操作的基本过程。
JWT的组成
JWT由三部分组成,包括:头部(Header)、载荷(Payload)、签名(Signature),将这3个部分以特定的算法进行编码处理,并使用“.”-点符号连接起来,就得到一个JWT字符串,也即:Token令牌。
头部(Header)
JWT的头部包括::token的类型(“JWT”)和加密/解密算法名称(比如:HMAC SHA256或者RSA等等)。如下图所示,
载荷(Payload)
载荷(payload)主要用来包含声明(claims ),这个声明一般是关于实体(通常是用户)和其他数据的声明,例如:用户信息,如下图所示,
签名(Signature)
签名(Signature),得到前两部分,即:头部(Header)和载荷(Payload)之后,就需要将这两部分拼接完的字符串用HS256算法进行加密,在加密的时候,还需要提供一个密钥(secret),将其加密处理之后的也得到一个字符串,这个字符串就是签名(Signature)。
JWT的实现版本
JWT提供了不同语言版本的依赖库,如:C#、Python、Java、Node.js等等,其官网地址为:jwt.io/libraries 。
JWT与Java项目的整合
依赖引入
对于Maven项目,可以直接将JWT(GitHub地址:github.com/auth0/java-… 的依赖坐标配置到pom.xml文件中即可,如下,
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.2.1</version>
</dependency>
创建&验证JWT
工具类封装
public class XJWTool {
//properties
private static final Integer EXPIRED_TIME = 60*1;//过期时长
private static final String SECRET = "hdsakdsald,asd16dasd465adankga15hdfgsfa";//jwt 密钥
//methods
/**
* 根据Claim声明获取Token
* @param map 包含<key,value>的键值对属性
* @return String字符串格式的Token
*/
public static String getToken(Map<String,String> map){
//创建Algorithm算法
Algorithm algorithm = Algorithm.HMAC256(SECRET);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE,EXPIRED_TIME);
//创建Token
JWTCreator.Builder builder = JWT.create();
//添加Claim声明
map.forEach(builder::withClaim);
//指定过期时间
builder.withExpiresAt(calendar.getTime());
//指定算法-生成Token
return builder.sign(algorithm);
}
/**
* 验证token的合法性
* @param token token令牌值
* throw 抛出异常-表示验证失败
*/
public synchronized static void decodeToken(String token){
JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
}
/**
* 获取token信息的方法
* @param token token令牌值
* @return DecodedJWT对象
* throw 抛出异常-表示验证失败
*/
public synchronized static DecodedJWT getTokenInfo(String token){
DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
return decodedJWT;
}
}
示例代码
@Test
public void JWTTool_Test(){
Map<String,String> map = new HashMap<>();
map.put("name","Tom");
map.put("password","123456");
map.put("age","30");
String token = XJWTool.getToken(map);
System.out.println(token);
//验证Token
XJWTool.decodeToken(token);
}