public static void main(String[] args) throws InterruptedException, IOException {
String key = UUID.randomUUID().toString();
long l = LocalDateTime.now().plusSeconds(10).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
Date expireAt = new Date(l);
Operator operator2 = JwtUtil.builder().secret(key).audience("admin").issure("admin").expireAt(expireAt).generator().build();
System.out.println(operator2);
TimeUnit.SECONDS.sleep(2);
Operator operator3 = JwtUtil.builder().secret(key).audience("admin").issure("admin").token(operator2.getToken()).verify().build();
System.out.println(operator3);
}
可以看到上述的代码好似和我们熟知建造者模式类似, 但是在编译器里写的是否, 会发现, 你做了第一步之后,下一步是什么,是完全自动提示的, 不需要再有额外的文档阐述, 我觉得这种是非常好的,程序自带解释.
下面是idea的自动提示截图:
可以看到整个JwtUtil工具类已有了自我解释能力,我非常欣赏这样的工具包,就如cola的状态及,okhttp一样, 用起来是非常好用的.
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.*;
public class JwtUtil implements Builder, Secret, Audience, Issure, Token, ExpireAt, Generator, Verify, Operator {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final String BEARER = "Bearer ";
private String secret;
private String[] audience;
private String issure;
private String token;
private Date expireAt;
private String jwtId;
private String keyId;
private Date issuedAt;
private final Map payload = new HashMap<>();
private JWTVerifier jwtVerifier;
private DecodedJWT decodedJWT;
private JwtUtil() {
}
public static Builder builder() {
return new JwtUtil();
}
@Override
public Secret secret(String secret) {
this.secret = secret;
return this;
}
@Override
public Audience audience(String... audience) {
this.audience = audience;
return this;
}
@Override
public Issure issure(String issure) {
this.issure = issure;
return this;
}
@Override
public Token token(String token) {
this.token = token;
return this;
}
@Override
public ExpireAt expireAt(Date expireAt) {
this.expireAt = expireAt;
return this;
}
@Override
public Generator generator(Map payload) {
JWTCreator.Builder builder = JWT.create();
this.issuedAt = new Date();
this.jwtId = UUID.randomUUID().toString().toUpperCase();
this.keyId = UUID.randomUUID().toString().toUpperCase();
if (payload != null) {
this.payload.putAll(payload);
}
builder
.withExpiresAt(this.expireAt)
.withIssuedAt(this.issuedAt)
.withIssuer(this.issure)
.withAudience(this.audience)
.withJWTId(this.jwtId)
.withKeyId(this.keyId)
.withPayload(this.payload)
;
this.token = BEARER+builder.sign(Algorithm.HMAC256(this.secret));
this.payload.put("iss", this.issure);
this.payload.put("aud", this.audience);
this.payload.put("exp", this.expireAt.getTime() / 1000);
this.payload.put("jti", this.jwtId);
this.payload.put("iat", this.issuedAt.getTime()/1000);
return this;
}
@Override
public Generator generator() {
return this.generator(null);
}
@Override
public Verify verify() throws IOException {
if (this.jwtVerifier == null) {
this.jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
}
if (this.decodedJWT == null) {
this.decodedJWT = jwtVerifier.verify(token.replace(BEARER,""));
this.audience = this.decodedJWT.getAudience().toArray(new String[0]);
this.issure = this.decodedJWT.getIssuer();
this.issuedAt = this.decodedJWT.getIssuedAt();
this.expireAt = this.decodedJWT.getExpiresAt();
this.jwtId = this.decodedJWT.getId();
this.keyId = this.decodedJWT.getKeyId();
this.payload.putAll(OBJECT_MAPPER.readValue(Base64.getUrlDecoder().decode(this.decodedJWT.getPayload()), new TypeReference
import lombok.NonNull;
public interface Audience {
Issure issure(@NonNull String issure);
}
import lombok.NonNull;
public interface Builder {
Secret secret(@NonNull String secret);
}
import java.util.Map;
public interface ExpireAt {
Generator generator(Map payload);
Generator generator();
}
public interface Generator {
Operator build();
}
import lombok.NonNull;
import java.util.Date;
public interface Issure {
Token token(@NonNull String token);
ExpireAt expireAt(@NonNull Date expireAt);
}
public interface Operator {
String getSecret();
String[] getAudience();
String getIssure();
String getToken();
Date getExpireAt();
String getJwtId();
String getKeyId();
Date getIssuedAt();
Map getPayload();
boolean getClaimAsBool(String name);
int getClaimAsInt(String name);
long getClaimAsLong(String name);
Object getClaim(String name);
String getClaimAsString(String name);
}
import lombok.NonNull;
public interface Secret {
Audience audience(@NonNull String... audience);
}
import java.io.IOException;
public interface Token {
Verify verify() throws IOException;
}
public interface Verify {
Operator build();
}
源码地址: https://github.com/zhangpan-soft/dv-commons