JWT生成的Token大概是下图这样的:
它分为三个部分,分别是:
- 头部(header):带有类型和加密算法信息
- 载荷(payload):带有过期时间、签发者和自定义信息
- 签证(signature):首先将 header 和 payload 信息进行 Base64 编码,然后将他们进行带盐加密得到密文,最后将这密文再进行 Base64 编码得到最终的 signature。
需要的依赖包
<!-- Token -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
实例
public class TokenTest {
/**
* SALT:盐,或称密钥。加密使用,需要服务端保管好
*/
private static final String SALT = "029ef05131b5501f319ae490354df5c9a23be01e3c1d40c79d5d52fe992dbe";
/**
* 创建 Token
* @param userName 用户名,用作于接口过滤。可根据具体的业务进行设置
* @return Token 字符串
*/
public static String createToken(String userName){
// 签发时间
Date issueDate = new Date();
// 过期时间
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.MINUTE, 480); // 8 小时过期
Date expireDate = nowTime.getTime();
Map<String, Object> headerMap = new HashMap<>();
headerMap.put("alg", "HMAC256"); // 声明算法
headerMap.put("typ", "JWT"); // 声明类型
return JWT.create()
.withHeader(headerMap) // header段,带有算法信息和类型信息
.withExpiresAt(expireDate) // payload段,设置过期时间
.withIssuedAt(issueDate) //payload段,设置签发时间
.withIssuer("HyugaNeji") // payload段,设置签发者
.withClaim("name", userName) // payload段,自定义信息
.sign(Algorithm.HMAC256(SALT)); // signature段,进行加盐加密
}
/**
* 验证 Token
* @param token token 字符串
* @return 这里我选择取回 payload 段的信息,因为里面有自定义信息,我可以拿来处理业务逻辑
*/
public static Map<String, Claim> verifyToken(String token) {
if(token != null){
// 解密也需要该 salt,所以它很重要,不要泄露
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SALT)).build();
DecodedJWT jwt = verifier.verify(token);
if(SystemConstant.ISSUER.equals(jwt.getIssuer())){
return jwt.getClaims();
}
}
return null;
}
/**
* 模拟接口认证
*/
public static void main(String[] args) {
// 1. 取前端带过来的 token 信息。现在假设这就是前端带上来的数据
String token = "";
// 2. 验证 Token
boolean result = false;
// 取得 payload 段的信息
Map<String, Claim> claimMap = TokenTest.verifyToken(token);
if(claimMap != null){
// 取出里面的用户名
String userName = claimMap.get("name").asString();
// 检查该用户名是否存在,存在就放行,不存在就返回指定的信息
result = UserService.findAdminByName(userName) != null;
}
// 3. 处理结果
if(result){
// 放行
}else {
// 返回指定错误信息
}
}
}
技 术 无 他, 唯 有 熟 尔。
知 其 然, 也 知 其 所 以 然。
踏 实 一 些, 不 要 着 急, 你 想 要 的 岁 月 都 会 给 你。