- Spring Boot 版本:2.6.1
- redis 版本:6.2.6
- jwt 版本:0.6.0
- redisson 版本:3.13.6
除了/token开头的地址都拦截
@Configuration
public class InterceptorConfiguration extends WebMvcConfigurationSupport {
@Autowired
private TokenHandlerInterceptor tokenHandlerInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenHandlerInterceptor)
.addPathPatterns("
String tokenApply(String name, String secretKey, long time);
boolean verificationToken(String token) throws Exception;
boolean verificationToken(HttpServletRequest request) throws Exception;
String renewal(String oldToken, String name, long time);
}
jwt实现
@Service
public class JwtServiceImpl implements JwtService {
private static final Logger log = LoggerFactory.getLogger(JwtServiceImpl.class);
@Value("${jwt.secret}")
private String jwtSecret;
@Autowired
private RedissonClient redisson;
// 默认过期时间30天
private long jwtDefaultExpire = 1000L * 60 * 60 * 24 * 30;
@Override
public String tokenApply(String name, String secretKey, long time) {
long expire = time < 1 ? jwtDefaultExpire:time;
String jwtToken = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("app")
.setIssuedAt(new Date())
//设置过期时间
.setExpiration(new Date(System.currentTimeMillis() + expire))
.claim("user", name)
.signWith(SignatureAlgorithm.HS256, jwtSecret)
.compact();
redisson.getBucket(secretKey).set(jwtToken);
redisson.getBucket(secretKey).expire(expire, TimeUnit.MILLISECONDS);
return jwtToken;
}
@Override
public boolean verificationToken(String token) throws Exception {
return checkToken(token);
}
@Override
public boolean verificationToken(HttpServletRequest request) throws Exception {
return checkToken(request.getHeader("secret_key"))
|| checkToken(request.getHeader("access_token"))
|| checkToken(request.getHeader("token"));
}
@Override
public String renewal(String secretKey, String name, long time) {
Object oldToken = redisson.getBucket(secretKey).get();
Assert.isTrue(null != oldToken, "请先申请密匙");
Claims claims = decryptToken(oldToken.toString());
if(null == claims) {
// token过期,直接重新申请
return tokenApply(name, secretKey, time);
}
return tokenApply(name,
secretKey,
claims.getExpiration().getTime() - System.currentTimeMillis() + (time < 1 ? jwtDefaultExpire:time));
}
private boolean checkToken(String secretKeys) throws Exception {
if(null == secretKeys) return false;
Object data = redisson.getBucket(secretKeys).get();
Assert.isTrue(null != data, "密匙不存在或者已过期");
try {
Jws claimsJws = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(data.toString());
} catch (ExpiredJwtException e) {
throw new Exception("密匙过期或无效");
}
return true;
}
private Claims decryptToken(String token) {
try {
Jws claimsJws = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
return claimsJws.getBody();
} catch (ExpiredJwtException e) {
log.error("Jwts.parser error:", e);
}
return null;
}
}
申请token
@RestController
@RequestMapping("/token")
public class JwtTokenController {
@Autowired
private JwtService jwtService;
@Autowired
private RedissonClient redisson;
@PostMapping("/secretKeyApply")
public String secretKeyApply(@RequestParam String name, Long time) {
String secretKey = UUID.randomUUID().toString();
jwtService.tokenApply(name, secretKey, null == time ? -1:time.longValue());
return secretKey;
}
@PostMapping("/renewal")
public boolean renewal(@RequestParam String secretKey, @RequestParam String name, Long time) {
Assert.isTrue(null != secretKey, "密匙不能为空");
jwtService.renewal(secretKey, name, time);
return true;
}
@PostMapping("/abolish")
public boolean abolish(@RequestParam String secretKey) {
Assert.isTrue(null != secretKey, "密匙不能为空");
redisson.getBucket(secretKey).delete();
return true;
}
}
properties配置文件
redis.address=127.0.0.1:6379 redis.password=密码 jwt.secret=随机字符串
至此jwt校验就完成了
测试代码@RestController
@RequestMapping("/test")
public class TestJwtController {
@PostMapping("/testjwt")
public String testJwt() {
return "verification token success";
}
}
直接访问:localhost:8080/test/testjwt 接口
调用申请token接口:localhost:8080/token/secretKeyApply,申请token
将申请的token放入header中,请求成功



