本文讲解SpringBoot项目集成JWT的基础用法
1.新建SpringBoot项目(本案例使用 2.7.X 版)
2.依赖(pom.xml)
除基本的 spring-boot-starter-web 包之外,需要导入的 JWT 相关的包有:
<!--JWT 包-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.2</version>
</dependency>
<!--JWT 工具包-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.配置文件(application.properties)
自定义的配置信息:密钥和token的过期时间
# 密钥
jwt.secret=123456
# tocken 过期时间,单位毫秒
jwt.expire=60000
如果使用的yaml配置文件,写法是
jwt:
secret: 123456
expire: 60000
3.定义JWT工具类
包名:utils
类名:JWTUtil
package com.hu.springbootjwt.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.*;
/**
JWT的工具类
*/
@Component
public class JWTUtil {
// 生成签名的秘钥(来自配置文件项的jwt.secret)
private static String key;
// jwt过期时间
private static long ttlMillis;
// 静态属性的注入必须显示set方法
// import org.springframework.beans.factory.annotation.Value;
// (来自配置文件项的jwt.secret)
@Value("${jwt.secret}")
public void setKey(String secret){
key=secret;
}
// (来自配置文件项的jwt.expire)
@Value("${jwt.expire}")
public void setTtlMillis(Long expire){
ttlMillis=expire;
}
/**
* 用户登录成功后生成Jwt
* 使用Hs256算法
*
* @param username 用户名
* @param password 用户密码
* @return token串
*/
public static String createJWT(String username,String password) {
// 使用的签名算法(header部分,jjwt包已封装,此处直接调用)
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 计算时间 (在后续使用)
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
// 创建payload的私有声明(在后续使用)
//(此处是存放的用户名和密码)
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("username", username);
claims.put("password",password);
// 通过JwtBuilder,设置jwt的body部分
JwtBuilder builder = Jwts.builder()
// 给builder的claim赋值(放入 payload 的私有声明,必须先写)
.setClaims(claims)
// 设置JWT ID(JWT的唯一标识)
// 根据业务需要设置为一个不重复的值,用来作为一次性token, 从而回避重放攻击。
.setId(UUID.randomUUID().toString())
// 设置jwt的签发时间
.setIssuedAt(now)
// 所有人,作为用户的唯一标志
.setSubject(username)
// 设置秘钥
.signWith(signatureAlgorithm, key);
//设置过期时间
if (ttlMillis >= 0) {
// 相对于当前时刻,在 ttlMillis 属性设置的时间后过期
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp);
}
return builder.compact();
}
/**
* Token的解密
* @param token 加密后的token
* @return 解密后的token
*/
public static Claims parseJWT(String token) {
// 使默认的JWT解析器
Claims claims = Jwts.parser()
// 秘钥
.setSigningKey(key)
// 获取 token 的内容
.parseClaimsJws(token).getBody();
return claims;
}
/**
* 校验token
* (校验逻辑是:token 携带的password 是否与传入的密码一致
* @param token 原始token(加密的)
* @param password 传入的密码
* @return 是否校验成功
*/
public static Boolean isVerify(String token, String password) {
try {
// 调用上面写的parseJWT方法
Claims claims = parseJWT(token);
// 校验
if (claims.get("password").equals(password)) {
return true;
}
}
catch (ExpiredJwtException e){
e.printStackTrace();
}
return false;
}
}
4.控制器
在页面调用过程中测试 JWT 工具类的使用
@RestController
public class TestController {
// 创建token
@PostMapping("/get")
public String creatToken2(){
return JWTUtil.createJWT("zhangsan","123");
}
// 解析和校验token
@PostMapping("/test")
public String testToken2(HttpServletRequest request, HttpServletResponse response){
String token= request.getHeader("Authorization");
if (JWTUtil.isVerify(token,"123")){
return "通过";
}
return "失败";
}
}
5.测试:
第一次请求:http://localhost:8080/get
第一次结果:得到下面的token串 (每次请求会有变化)
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ6aGFuZ3NhbiIsInBhc3N3b3JkIjoiMTIzIiwiZXhwIjoxNjU0ODMwOTgzLCJpYXQiOjE2NTQ4MzA5ODMsImp0aSI6ImY5MTMwMjBlLThhOWItNDg3Ni1iOTM1LTRiNjA3Mjk1MzE0MiIsInVzZXJuYW1lIjoiemhhbmdzYW4ifQ.mGZfLOQJJxBkJGsf9Li7doaHhoGGv0Kz84V1at0Q4OI
第二次请求:http://localhost:8080/test
Authorization: 放入第一次请求拿到的token串(不要有换行)
第二次结果:通过
如果没有token串或token串错误(含过期)都会显示 “失败” 的结果
关于测试工具:使用postman或swagger,下面是使用的swagger+knife4j ,在全局参数设置页面,添加 Authorization 参数,其参数的值为 token 串





