JWT入门简介 (2)

以Java语言为例,我们完全可以按照JWT的定义格式自己签发JWT。

// 手动实现JWT签发 // 需要注意的是:使用JDK自带的Base64工具类编码的结果可能会以"=="结尾,需要去掉这个字符 public class JWTUtil { public static void main(String[] args) throws InvalidKeyException { // 构造头部 JSONObject headerJson = new JSONObject(); headerJson.put("typ", "JWT"); headerJson.put("alg", "HS256"); String header = base64Encode(headerJson.toJSONString().getBytes()); // 构造载荷 JSONObject payloadJson = new JSONObject(); payloadJson.put("iss", "iss0"); payloadJson.put("sub", "1234567890"); payloadJson.put("name", "zhangsan"); payloadJson.put("admin", true); String payload = base64Encode(payloadJson.toJSONString().getBytes()); // 加密 String secret = "secret"; String encodeStr = header + "." + payload; String signature = HMACSHA256(encodeStr.getBytes(), secret.getBytes()); String jwt = new StringBuilder() .append(header) .append(".") .append(payload) .append(".") .append(signature) .toString(); System.out.println(jwt); } // 使用HMAC256加密 private static String HMACSHA256(byte[] data, byte[] key) throws InvalidKeyException { try { SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); return base64Encode(mac.doFinal(data)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } return null; } // base64编码 private static String base64Encode(byte[] bytes) { String encode = Base64.getEncoder().encodeToString(bytes); int index = encode.indexOf("="); if(index > 0) { encode = encode.substring(0, index); } return encode; } } 使用类库签发JWT

从JWT的官网可以看到,目前已经有多种语言版本JWT的实现库。
以Java库为例,完全支持JWT公共声明和常用加密算法的库有3个,分别是:java-jwt,jose4j,jjwt,比较如下:

名称 易用性 性能(ms) 热度 地址
java-jwt     180   1812   https://github.com/auth0/java-jwt  
jose4j     258   NaN   https://bitbucket.org/b_c/jose4j/wiki/Home  
jjwt     292   3187   https://github.com/jwtk/jjwt  

附: 性能是指连续生成10次JWT所需要的平均耗时时间(单位:毫秒)。

鉴于易用性和性能方面的考虑,如下示例以使用java-jwt库进行说明,更加详细的使用请参考各个实现库官方文档。

添加依赖

<!-- 集成JWT类库 --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.3.0</version> </dependency>

服务端签发和验证JWT

@RestController @RequestMapping("/jwt") public class JwtController { private String secret = "secret"; private String iss = "iss0"; private String sub = "1234567890"; private String key = null; // 模拟用户登录,并在登录请求响应中返回JWT @PostMapping("/login") public Object login(HttpServletRequest req, HttpServletResponse resp, @RequestBody JSONObject user) { // 用户名和密码 String userName = user.getString("username"); String passwrod = user.getString("passwrod"); // 使用类库签发JWT try { Algorithm algorithm = Algorithm.HMAC256(this.secret); String jwt = JWT.create() .withIssuer(iss) .withSubject(sub) //.withAudience(auArr) //.withExpiresAt(exp) //.withNotBefore(nbf) //.withIssuedAt(iat) //.withJWTId(jti) .withClaim("name", userName) .withClaim("admin", true) .sign(algorithm); JSONObject data = new JSONObject(); data.put("code", 200); data.put("message", "success"); data.put("data", jwt); return data; } catch (UnsupportedEncodingException e){ //UTF-8 encoding not supported e.printStackTrace(); } catch (JWTCreationException e){ //Invalid Signing configuration / Couldn\'t convert Claims. e.printStackTrace(); } return null; } // 模拟在用户登录之后将JWT通过HTTP消息头返回给服务端进行验证 @GetMapping("/list") public Object list(HttpServletRequest req, HttpServletResponse resp) { String auth = req.getHeader("Authorization"); if(auth != null) { String jwt = auth.split(" ")[1]; try { Algorithm algorithm = Algorithm.HMAC256(this.secret); JWTVerifier verifier = JWT.require(algorithm) .withIssuer(this.iss) .build(); //Reusable verifier instance DecodedJWT jwtDecode = verifier.verify(jwt); System.out.println("========================="); System.out.println(jwtDecode.getClaim("name").asString()); System.out.println(jwtDecode.getClaim("admin").asBoolean()); System.out.println("========================="); } catch (UnsupportedEncodingException e){ //UTF-8 encoding not supported e.printStackTrace(); } catch (JWTVerificationException e){ //Invalid signature/claims e.printStackTrace(); } } List<String> list = new ArrayList<String>(); list.add("张三"); list.add("李四"); JSONObject data = new JSONObject(); data.put("code", 200); data.put("message", "success"); data.put("data", list); return data; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzppyg.html