系列文章:
权限与认证: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(); } }
复制代码
评论