关于依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<!-- Uncomment this next dependency if you are using JDK 10 or earlier and you also want to use
RSASSA-PSS (PS256, PS384, PS512) algorithms. JDK 11 or later does not require it for those algorithms:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
<scope>runtime</scope>
</dependency>
-->
复制代码
快速开始
生成JWS
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
//创建一个签名密钥,通常在配置文件中设置
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();
复制代码
- 调用Jwts.builder()创建JWT实例;
- 设置subject=joe
- 使用key签名
- 调用compact()生成jws
输出如下: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.1KP0SsvENi7Uz1oQc07aXTL7kpQG5jBNIybqr60AlD4
验证
通常我们需要对拿到的JWS进行验证,以丢弃错误的JWS。
assert Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jws)
.getBody().getSubject().equals("Joe");
复制代码
- 首先验证jws的签名是否正确
- 验证subject是否等于joe
异常
如果解析错误,可通过接收异常进行判断:
try {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compactJws);
//OK, we can trust this JWT
} catch (JwtException e) {
//don't trust the JWT!
}
复制代码
JWTs签名
签名首先保证jwts是正确的,然后保证没有被篡改
签名过程(伪代码)
- 假如有以下header、body内容:
// header
{
"alg": "HS256"
}
//body
{
"sub": "Joe"
}
复制代码
- 删除不必要的空白:
String header = '{"alg":"HS256"}'
String claims = '{"sub":"Joe"}'
复制代码
- 获取UTF-8字节和base64url编码
String encodedHeader = base64URLEncode( header.getBytes("UTF-8") )
String encodedClaims = base64URLEncode( claims.getBytes("UTF-8") )
复制代码
- 将编码后的头文件和声明文件之间用句点字符连接起来
String concatenated = encodedHeader + '.' + encodedClaims
复制代码
- 使用足够强的加密密钥或私钥,以及您选择的签名算法(这里我们将使用HMAC-SHA-256),并对连接的字符串签名:
Key key = getMySecretKey()
byte[] signature = hmacSha256( concatenated, key )
复制代码