1.JWT的介绍
知乎有一篇文章介绍的很形象 认证方式的前世今生,以及 JWT 的使用
具体和Springboot的集成使用可参考另一篇博客:SpringBoot集成JWT实现token验证
2.使用demo
1 package com.drz.proxy.internetProxy.util; 2 3 import java.util.Date; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import org.apache.commons.codec.binary.Base64; 8 import org.apache.commons.codec.binary.StringUtils; 9 10 import com.auth0.jwt.JWT; 11 import com.auth0.jwt.JWTVerifier; 12 import com.auth0.jwt.algorithms.Algorithm; 13 import com.auth0.jwt.exceptions.JWTCreationException; 14 import com.auth0.jwt.exceptions.JWTVerificationException; 15 import com.auth0.jwt.interfaces.DecodedJWT; 16 17 /** 18 * JWT token串结构: header.payload.signature 19 * signature=HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),Secret) 20 * 21 * token保存在客户端,每次请求传到后端,服务端只保留密钥,不要把密钥放在header和payload中; 22 * 23 * header中默认传递参数: 24 * {"typ":"JWT","alg":"HS256"} 25 * 26 * payload官方定义包含属性如下(非强制): 27 * iss: jwt签发者 28 * sub: jwt所面向的用户 29 * aud: 接收jwt的一方 30 * exp: jwt的过期时间,这个过期时间必须要大于签发时间 31 * nbf: 定义在什么时间之前,该jwt都是不可用的. 32 * iat: jwt的签发时间 33 * jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 34 * payload 自定义数据:存放我们想放在token中存放的key-value值 35 */ 36 public class JWTUtil { 37 38 /** 39 * 过期时间 40 */ 41 private static final long EXPIRE_TIMEMILLS = 6000; 42 43 /** 44 * jwt 密钥 45 */ 46 private static final String SECRET = "jwt_secret"; 47 48 public static String create() { 49 try { 50 Algorithm algorithm = Algorithm.HMAC256(SECRET); 51 52 Map<String, Object> headerMap = new HashMap<String, Object>(); 53 headerMap.put("date", "2022-01-01 18:00"); 54 headerMap.put("where", "城东小树林"); 55 String token = JWT.create().withHeader(headerMap)//可自定义传递参数 56 // .withIssuer("auth0")//签发者 57 .withIssuedAt(new Date())//签发时间 58 .withSubject("subject").withAudience("100102134") 59 .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE_TIMEMILLS)) 60 //payload中加入自定义数据 61 .withClaim("name", "小明").withClaim("introduce", "TTT").sign(algorithm); 62 System.out.println("当前时间:" + new Date()); 63 System.out.println("jwt token:" + token); 64 return token; 65 } catch (JWTCreationException exception) { 66 //Invalid Signing configuration / Couldn't convert Claims. 67 throw exception; 68 } 69 } 70 71 public static Boolean verify(String token) { 72 try { 73 Algorithm algorithm = Algorithm.HMAC256(SECRET); 74 JWTVerifier verifier = JWT.require(algorithm).build(); //Reusable verifier instance 75 DecodedJWT jwt = verifier.verify(token); 76 77 String decodeHeader = StringUtils.newStringUtf8(Base64.decodeBase64(jwt.getHeader())); 78 String decodePayload = StringUtils.newStringUtf8(Base64.decodeBase64(jwt.getPayload())); 79 80 String signature = jwt.getSignature(); 81 String name = jwt.getClaim("name").asString(); 82 String introduce = jwt.getClaim("introduce").asString(); 83 84 System.out.println("header:" + jwt.getHeader()); 85 System.out.println("payload:" + jwt.getPayload()); 86 System.out.println("signature:" + signature); 87 88 System.out.println("headerString:" + decodeHeader); 89 System.out.println("payloadString:" + decodePayload); 90 91 System.out.println("name:" + name); 92 System.out.println("introduce:" + introduce); 93 return true; 94 } catch (JWTVerificationException exception) { 95 System.out.println("当前时间:" + new Date()); 96 System.out.println("验证token失败:" + exception.getMessage()); 97 return false; 98 } 99 } 100 101 public static void main(String[] args) { 102 String token = create(); 103 // try { 104 // Thread.sleep(3000l); 105 // } catch (InterruptedException e) { 106 // // TODO Auto-generated catch block 107 // e.printStackTrace(); 108 // } 109 Boolean result = verify(token); 110 System.out.println(result); 111 } 112 }
输出结果:
当前时间:Wed Jan 27 10:15:44 CST 2021
jwt token:eyJkYXRlIjoiMjAyMi0wMS0wMSAxODowMCIsIndoZXJlIjoi5Z-O5Lic5bCP5qCR5p6XIiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJzdWIiOiJzdWJqZWN0IiwiYXVkIjoiMTAwMTAyMTM0IiwiaW50cm9kdWNlIjoiVFRUIiwibmFtZSI6IuWwj-aYjiIsImV4cCI6MTYxMTcxMzc1MCwiaWF0IjoxNjExNzEzNzQ0fQ.LQIg264ZYVpq8SfPpv8gwJ3WnZtn_yk8fH8Cwg9Z69k
header:eyJkYXRlIjoiMjAyMi0wMS0wMSAxODowMCIsIndoZXJlIjoi5Z-O5Lic5bCP5qCR5p6XIiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ
payload:eyJzdWIiOiJzdWJqZWN0IiwiYXVkIjoiMTAwMTAyMTM0IiwiaW50cm9kdWNlIjoiVFRUIiwibmFtZSI6IuWwj-aYjiIsImV4cCI6MTYxMTcxMzc1MCwiaWF0IjoxNjExNzEzNzQ0fQ
signature:LQIg264ZYVpq8SfPpv8gwJ3WnZtn_yk8fH8Cwg9Z69k
headerString:{"date":"2022-01-01 18:00","where":"城东小树林","typ":"JWT","alg":"HS256"}
payloadString:{"sub":"subject","aud":"100102134","introduce":"TTT","name":"小明","exp":1611713750,"iat":1611713744}
name:小明
introduce:TTT
true