首先创建一个springboot项目,注意springboot的版本需要2.7.6,或者是以下的版本,否则项目运行过程中可能会出现错误。
导入JWT相关依赖
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-gson</artifactId>
<version>0.11.5</version>
</dependency>
配置JWT参数
创建一个application.yml文件,将下列配置信息复制进文件中。
config:
jwt:
# 加密密钥
secret: abcdefg1234213213123123123123123123123213123123125gdfgdffdgfgdfdggfd23123123214214141231233332212121222222222222211122222222222222222222222222222222222222222222222222222222222222222222222222222222221111111111sadasdasdasdasdasdsadsadasdsadsadasdasdasdasdsad
# token有效时长
expire: 1000
# header 名称
header: token
创建JWT实体
可以创建一个JWT实体,将配置文件中的信息装入JWT实体中的成员变量上。在这里可以使用lombok组件,可以快速帮我们封装一个实体
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
注意实体中的成员变量的名称要和配置文件application.yml中的名称完全一致,才能将配置文件中的值赋给成员变量。首先使用@Configuration注解,将该配置类添加进springIOC容器中,再使用@ConfigurationProperties注解指定配置文件中需要赋值给成员变量的值的位置。
封装Token工具类
该工具类提供两个方法,分别为创建token和验证token是否过期。
import com.example.springbootjwt.config.JWTConfig;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
public class TokenUtil {
@Autowired
JWTConfig jwtConfig;
/**
* 生成token
* @param subject
* @return
*/
public String createToken (String subject){
Date nowDate = new Date();
Date expireDate = new Date(nowDate.getTime() + jwtConfig.getExpire() * 1000);//过期时间
return Jwts.builder()
.setHeaderParam("type", "JWT")
.setSubject(subject)
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret())
.compact();
}
/**
* 获取token中注册信息
* @param token
* @return
*/
public Claims getTokenClaim (String token) {
try {
return Jwts.parser().setSigningKey(jwtConfig.getSecret()).parseClaimsJws(token).getBody();
}catch (Exception e){
return null;
}
}
/**
* 验证token是否过期失效
* @param token
* @return
*/
public boolean isTokenExpired (String token) {
Date expirationTime = getTokenClaim(token).getExpiration();
return expirationTime.before(new Date());
}
}
创建拦截器
拦截器的作用是对前端发送过来的请求都要进行token验证,满足要求的请求放行,对不满足要求的请求拦截。
import com.example.springbootjwt.config.JWTConfig;
import com.example.springbootjwt.util.TokenUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
JWTConfig jwtConfig;
@Autowired
TokenUtil tokenUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setContentType("text/html;charset=utf-8");
// if(RequestMethod.OPTIONS.name().equals(request.getMethod())){//放行post get delete put ...
// return true;
// }
/** Token 验证 */
PrintWriter printWriter=response.getWriter();
String token = request.getHeader(jwtConfig.getHeader());
if(ObjectUtils.isEmpty(token)){
printWriter.println(jwtConfig.getHeader()+"不能为空");
return false;
}
Claims claims = null;
try{
claims = tokenUtil.getTokenClaim(token);
if(claims == null || tokenUtil.isTokenExpired(token)){
printWriter.println(jwtConfig.getHeader()+"已失效");
return false;
}
}catch (Exception e){
printWriter.println(jwtConfig.getHeader()+"已失效");
return false;
}finally {
printWriter.flush();
}
return true;
}
}
注册拦截器
将拦截器注入到IOC容器中,并设置拦截器所拦截的url。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
}
}
测试Token
最后定义一个controller,先发送login请求,获取到token后,将token放入http的header中,进行测试,测试token失效和token有效的情况。