Json Web Token的学习
Json Web Token是什么?
简称JWT,是一个非常轻巧的规范,也可以说本质上就是一个Token,这个规范设计成使我们可以方便直接的在用户和服务器获取信息或传递安全可靠的信息。
Json Web Token的结构
JWT本质上就是Token,也就是说是一个字符串(String),它由三部分组成:
1.header(头部)
示例:
{ "typ" : "JWT", // 类别,默认JWT就行 "alg" : "HS256" // 加密算法HS256 } // 上面是一个Json对象,对上面的Json对象进行base64编码,形成一串字符串如:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2.plyload(载荷)
示例:
{ "iss" : "John Wu JWT", // Token的签发者,谁生成的 "iat" : 1441593502, // 签发时间,生成Token的时间 "exp" : 1441594722, // 过期时间 "user" : "xxx" // 用户信息,如用户名,切勿放入敏感信息,如用户密码 } // 对上面的Json对象进行base64编码,形成一串字符串如:eyJ1aWQiOiJEU1NGQVdEV0FEQVMuLi4iLCJ1c2VyX25hbWUiOiJhZG1pbiIsIm5pY2tfbmFtZSI6IkRBU0RBMTIxIiwiZXhwIjoxNTI3NDk3ODkyLCJpYXQiOjE1Mjc0OTc4ODJ9
// 对于plyload(载荷)需要放入什么信息可以自己添加,但切勿放入敏感信息
3.signature(签名)
已经base64编码的header(头部)字符串加上一个句号.,再加上已经base64编码的plyload(载荷)字符串。再对其进行HS256算法的加密,加密时还需要一个密钥就形成了signature(签名)
如:G3YLI8hHB_eXsKFf-hjo2IERzfXk9f9QutSKlmt810E
最后把已经base64编码的header(头部),已经base64编码plyload(载荷),signature(签证)三个部分使用"."相连就形成Json Web Token,如: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJEU1NGQVdEV0FEQVMuLi4iLCJ1c2VyX25hbWUiOiJhZG1pbiIsIm5pY2tfbmFtZSI6IkRBU0RBMTIxIiwiZXhwIjoxNTI3NDk3ODkyLCJpYXQiOjE1Mjc0OTc4ODJ9.G3YLI8hHB_eXsKFf-hjo2IERzfXk9f9QutSKlmt810E
关于signature(签名)的作用:
我们使用Json Web Token的目的就是使用其中plyload(载荷)部分所携带的信息,当Json Web Token在用户和服务器之间传递时,可能会被恶意修改其中的信息。那么我们如何知道Json Web Token中的信息是否被修改呢?这时我们就需要signature(签名)了,当我们校验Json Web Token是否合法是否被修改时,我们需要使用header(头部)中携带alg属性的值,该值的作用就是标识使用什么加密算法,我们根据该加密算法再次对Json Web Token中的header(头部),plyload(载荷),和key密钥进行加密再次生成新的signature(签名)。然后使用新的signature(签名)与Json Web Token中携带的signature(签名)进行比较,如果不相同说明传递的Json Web Token被修改,如果相同就说明了传递的Json Web Token是合法的。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
使用jjwt第三方的Jar包生成Json Web Token
附上jjwt的github:https://github.com/jwtk/jjwt
注意本案例的项目是使用Maven构建的
1.在pom.xml中添加jjwt的依赖:
<!-- Json Web Token -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<!-- Json Web Token需要的依赖jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
2.在Java代码中生成Json Web Token的示例:
Key key = new SecretKeySpec("javastack".getBytes(), SignatureAlgorithm.HS256.getJcaName()); // 生成密钥,第二个参数是加密算法,这里使用的是HS256加密算法,可以选择其它加密算法
Map<String, Object> headerMap = new HashMap<>(); // 生成header(头部) headerMap.put("typ", "JWT"); headerMap.put("alg", "HS256"); Map<String,Object> payloadMap = new HashMap<>(); // 生成plyload(载荷) payloadMap.put("user_name", "admin"); long currTime = System.currentTimeMillis(); // 获取当前时间毫秒单位 // 加密生成Json Web Token String jsonWebToken = Jwts.builder() .setHeader(headerMap) // 设置header(头部) .setClaims(payloadMap) // 设置plyload(载荷) .setIssuedAt(new Date(currTime)) // 设置签发时间(可选设置) .setExpiration(new Date(currTime + (1000 * 10))) // 设置十秒后过期(可选设置) .signWith(SignatureAlgorithm.HS256, key) // 设置signature(签名),签证使用HS256加密算法,并且添加一个密钥 .compact();
// 通过上面的代码,jsonWebToken字符串对象就是最终生成的Json Web Token了。
3.在Java代码中解密Json Web Token的示例:
// 解密Json Web Token Jws<Claims> claimsJws = null; try { claimsJws = Jwts.parser() .setSigningKey(key) // 通过key密钥解密Json Web Token .parseClaimsJws(jsonWebToken); // 需要解密的Json Web Token字符串对象 }catch (ExpiredJwtException e){ // 抛出ExpiredJwtException异常说明Json Web Token已经过期了 System.out.println("Json Web Token已经过期了!"); }catch (SignatureException e){ // 抛出SignatureException异常可能是密钥错误或者Json Web Token被修改 System.out.println("解密Json Web Token异常!"); } JwsHeader header = claimsJws.getHeader(); // 取出header String alg = (String) header.get("alg"); // 取出header里的alg属性的值 Claims body = claimsJws.getBody(); // 取出payload String user_name = (String) body.get("user_name"); // 取出payload里的user_name属性的值
// 这样我们就可以从传递的Json Web Token中获取自己所需要的信息了
浙公网安备 33010602011771号