系列文章:
权限与认证:JWT
一 摘要
上一篇权限与认证:JWT中,我们详细介绍了 JWT,以及基于 Token 认证的机制,并描述了使用 JWT 的实现,即 JWT 的获取和使用 JWT 访问接口等资源的过程。本篇将通过一个实例,来了解 JWT 如何在实战中应用。
二 JWT 在 Java 中的使用
由于最近项目都是使用 Java 语言开发,所以这里我们还是介绍 Java 下的 JWT 使用示例。首先是依赖的引用。在各种轮子已经非常丰富的背景下,我们没有必要从头实现一个 JWT 框架,所以直接引用已有的框架。
2.1 JWT 依赖
新建一个空的 maven 项目,引入依赖。pom.xml 中,<dependencies></dependencies>标签下需要引入的依赖如下:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
复制代码
依赖包 com.auth0.java-jwt,版本我们这里使用的是 3.4.0。
除了这个包之外,也可以使用下面的依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
复制代码
我们先用 com.auth0.java-jwt 这个依赖包作为示例依赖。
2.2 简单使用示例
先从 0 开始,看怎样使用 JWT 生成 token。
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
public class JWTTest {
public static String createToken(String userId, String password) {
String token = JWT.create()
.withAudience(String.valueOf(userId))
.sign(Algorithm.HMAC256(password));
return token;
}
public static void main(String[] args){
String userId = "admin";
String password = "123456";
String token =JWTTest.createToken(userId, password);
System.out.println(token);
}
}
复制代码
直接执行,控制台输出内容:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhZG1pbiJ9.izglxuahSQb5by40gXqT1IcVbhmZQsE8cBu4X8tZKM0
复制代码
这就是一个 JWT。大家可以回顾上一张 JWT 的结构。
2.3 代码说明
通过上一篇 JWT 结构的对照,发现步骤基本一致。
1)JWT.create()方法创建 JWT 的 Builder,这显然是一个建造者模式。
2)然后 withAudience() 添加载荷信息;返回的仍然是一个 JWTCreator.Builder;
3)sign(Algorithm.HMAC256(password))方法对内容加密并计算签名,加密算法使用 HMAC256 算法,并且使用我们的参数 password 作为私钥。
至此,完成了一个 JWT 的生成。
三 框架源码分析
核心源码主要是两个类:JWT 和 JWTCreator。JWT 是一个抽象类,定义一个建造者,在 create()方法中会初始化 JWTCreator:
public abstract class JWT {
public JWT() {
}
public static DecodedJWT decode(String token) throws JWTDecodeException {
return new JWTDecoder(token);
}
public static Verification require(Algorithm algorithm) {
return JWTVerifier.init(algorithm);
}
public static Builder create() {
return JWTCreator.init();
}
}
复制代码
JWTCreate 是真正执行创建的类,初始化方法:
static JWTCreator.Builder init() {
return new JWTCreator.Builder();
}
复制代码
里面还有一个静态类 Builder,内容较多,这里只介绍核心属性和关键方法:
两个属性:payloadClaims 和 headerClaims:
private final Map<String, Object> payloadClaims = new HashMap();
private Map<String, Object> headerClaims = new HashMap();
复制代码
添加载荷信息:
public JWTCreator.Builder withAudience(String... audience) {
this.addClaim("aud", audience);
return this;
}
复制代码
签名方法:
public String sign(Algorithm algorithm) throws IllegalArgumentException, JWTCreationException {
if (algorithm == null) {
throw new IllegalArgumentException("The Algorithm cannot be null.");
} else {
this.headerClaims.put("alg", algorithm.getName());
this.headerClaims.put("typ", "JWT");
String signingKeyId = algorithm.getSigningKeyId();
if (signingKeyId != null) {
this.withKeyId(signingKeyId);
}
return (new JWTCreator(algorithm, this.headerClaims, this.payloadClaims)).sign();
}
}
复制代码
评论