前言
之前我们从研究官方文档去学习 jjwt 的使用, 本文做一个jwt的完整使用jar
实现
maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <dependencies> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency>
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> </dependencies>
|
常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class Conf {
public static final String SYS_ENV = "IDEA360_HOME";
public static final String DEFAULT_CONF_NAME = "conf.properties";
public static final String PRIVATEKEY_CONF = "idea360.auth.jwt.privatekey";
public static final String PUBLICKEY_CONF = "idea360.auth.jwt.publicKey"; }
|
配置文件加载器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public class ConfigLoader {
private static ConfigLoader instance = null; private Properties globalConfigs = null;
public static ConfigLoader getInstance() { if (instance == null) { instance = new ConfigLoader(); } return instance; }
private ConfigLoader() { this.init(); }
private void init() { boolean hasConfig = this.checkHasConfig(System.getenv(Conf.SYS_ENV)); if (!hasConfig) { throw new RuntimeException("没找到全局配置文件"); } }
private boolean checkHasConfig(String baseEnv) { String defaultPath = baseEnv + File.separator + "conf" + File.separator; File file = new File(defaultPath); if (file.exists() && file.isDirectory()) { File conf = new File(defaultPath + Conf.DEFAULT_CONF_NAME); if (conf.exists() && conf.isFile()) { this.globalConfigs = new Properties(); try { FileInputStream inputStream = new FileInputStream(conf); this.globalConfigs.load(inputStream); inputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return true; } else { return false; } }
public String getProperty(String key) { return this.globalConfigs.getProperty(key, null); } }
|
负载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| public class Payload implements Serializable {
private Integer companyId;
private String userId;
private String appId;
public Payload(Integer companyId, String userId, String appId) { this.companyId = companyId; this.userId = userId; this.appId = appId; }
public Integer getCompanyId() { return companyId; }
public void setCompanyId(Integer companyId) { this.companyId = companyId; }
public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; }
public String getAppId() { return appId; }
public void setAppId(String appId) { this.appId = appId; }
@Override public String toString() { return "Payload{" + "companyId=" + companyId + ", userId='" + userId + '\'' + ", appId='" + appId + '\'' + '}'; }
public static PayloadBuilder builder() { return new PayloadBuilder(); }
public static class PayloadBuilder { private Integer companyId; private String userId; private String appId;
public PayloadBuilder() { }
public PayloadBuilder setCompanyId(Integer companyId) { this.companyId = companyId; return this; }
public PayloadBuilder setUserId(String userId) { this.userId = userId; return this; }
public PayloadBuilder setAppId(String appId) { this.appId = appId; return this; }
public Payload build() { return new Payload(this.companyId, this.userId, this.appId); }
@Override public String toString() { return "PayloadBuilder{" + "companyId=" + companyId + ", userId='" + userId + '\'' + ", appId='" + appId + '\'' + '}'; } } }
|
Token工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
| public class JwtGenerator {
private static Logger log = LoggerFactory.getLogger(JwtGenerator.class);
private final Long DEFAULT_EXPIRE_TIME = 2L; private String privateKey; private String publicKey;
public JwtGenerator() { this.loadPrivateKey(); }
private void loadPrivateKey() { String privatekeyProperty = ConfigLoader.getInstance().getProperty(Conf.PRIVATEKEY_CONF); String publickeyProperty = ConfigLoader.getInstance().getProperty(Conf.PUBLICKEY_CONF);
this.privateKey = privatekeyProperty; this.publicKey = publickeyProperty; }
public String generateToken(Payload payload) throws InvalidKeySpecException, NoSuchAlgorithmException { return this.generateToken(payload, DEFAULT_EXPIRE_TIME); }
public String generateToken(Payload payload, Long expire) throws InvalidKeySpecException, NoSuchAlgorithmException { if (Objects.isNull(payload.getCompanyId()) || Objects.isNull(payload.getUserId())) { throw new NullPointerException("companyId和userId不能为空"); }
if (Objects.isNull(privateKey) || "".equals(privateKey)) { throw new NullPointerException("请检查私钥配置是否正确: " + Conf.PRIVATEKEY_CONF); }
String resourceKey = readResourceKey(privateKey); if (Objects.isNull(resourceKey)) { throw new NullPointerException("请检查私钥文件是否正确"); } PrivateKey privateKey = getPrivateKey(resourceKey);
expire = Objects.isNull(expire) || expire <= 0L? DEFAULT_EXPIRE_TIME : expire;
String token = Jwts.builder().setSubject("易聊科技") .setIssuer("易聊科技") .setIssuedAt(Date.from(Instant.now())) .setExpiration(Date.from(Instant.now().plus(expire, ChronoUnit.MINUTES))) .claim("companyId", payload.getCompanyId()) .claim("userId", payload.getUserId()) .claim("appId", payload.getAppId()) .signWith(SignatureAlgorithm.RS256, privateKey) .setId(UUID.randomUUID().toString()) .compact();
log.info("Generator Token: [{}]", token); return token; }
public Payload verifyToken(String token) throws InvalidKeySpecException, NoSuchAlgorithmException { if (Objects.isNull(token) || "".equals(token)) { throw new NullPointerException("token不能为空"); }
if (Objects.isNull(publicKey) || "".equals(publicKey)) { throw new NullPointerException("请检查公钥配置是否正确: " + Conf.PUBLICKEY_CONF); }
String resourceKey = readResourceKey(publicKey); if (Objects.isNull(resourceKey)) { throw new NullPointerException("请检查公钥文件是否正确"); } PublicKey publicKey = getPublicKey(resourceKey);
try { Jws<Claims> jws = Jwts.parser() .setSigningKey(publicKey) .parseClaimsJws(token);
log.info("Header : [{}]", jws.getHeader()); log.info("Body : [{}]", jws.getBody()); log.info("Signature : [{}]", jws.getSignature());
Claims claims = jws.getBody(); String appId = claims.get("appId", String.class); String userId = claims.get("userId", String.class); Integer companyId = claims.get("companyId", Integer.class); return Payload.builder().setCompanyId(companyId).setUserId(userId).setAppId(appId).build();
} catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException e) { log.error("token校验失败: " + e); } return null; }
private PrivateKey getPrivateKey(String rsaPrivateKey) throws NoSuchAlgorithmException, InvalidKeySpecException { rsaPrivateKey = rsaPrivateKey.replace("-----BEGIN RSA PRIVATE KEY-----", ""); rsaPrivateKey = rsaPrivateKey.replace("-----END RSA PRIVATE KEY-----", "");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(rsaPrivateKey)); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate(keySpec); }
private PublicKey getPublicKey(String rsaPublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException { rsaPublicKey = rsaPublicKey.replace("-----BEGIN PUBLIC KEY-----", ""); rsaPublicKey = rsaPublicKey.replace("-----END PUBLIC KEY-----", ""); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(rsaPublicKey)); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePublic(keySpec); }
private String readResourceKey(String fileName) { String key = null; try { File file = new File(fileName); if (file.exists() && file.isFile()) { List<String> lines = FileUtils.readLines(file, Charset.defaultCharset()); lines = lines.subList(1, lines.size() - 1); key = String.join("", lines); } } catch (IOException e) { log.error("读取私钥失败", e); } return key; }
}
|
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。