引入jar包
com.auth0 java-jwt3.10.3
加入jwt工具类
@Slf4j
@Component
public class JwtUtil {
private static final String secret = "secret";
public static String createToken(String username, Long time) throws UnsupportedEncodingException {
long expiration = System.currentTimeMillis() + time;
Date expireDate = new Date(expiration);
log.info("时间:{}----------------------",expireDate);
String token = JWT.create()
.withClaim("sys_username", username)
.withExpiresAt(expireDate)
.sign(Algorithm.HMAC256(secret));
log.info("用户:{} =====> token:{}", username, token);
return token;
}
public static boolean verify(String token, String username) throws UnsupportedEncodingException, TokenExpiredException {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("sys_username", username)
.build();
verifier.verify(token);
return true;
}
public static String getUsername(String token) {
DecodedJWT decode = JWT.decode(token);
return decode.getClaim("sys_username").asString();
}
public static boolean isExpired(String token) {
try {
final Date expiration = getExpiration(token);
return expiration.before(new Date());
} catch (JWTDecodeException JWT) {
return true;
}
}
public static Date getExpiration(String token) {
return JWT.decode(token).getExpiresAt();
}
}
配置拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
// 拦截所有请求,通过判断是否有 @JwtToken 注解 决定是否需要登录
.addPathPatterns("
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
添加自定义注解Token使用该注解的方法则被拦截
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
String value() default "0";
}
拦截方法此处为了方便把用户名当角色使用
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws IOException {
// 从 http 请求头中取出 token
String token = httpServletRequest.getHeader("token");
// 如果不是映射到方法直接通过
if(!(object instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod=(HandlerMethod)object;
Method method=handlerMethod.getMethod();
//检查有没有携带Token,携带则进入校验
if (method.isAnnotationPresent(Token.class)) {
Token tokenMethod = method.getAnnotation(Token.class);
// 执行认证
if (token == null) {
httpServletResponse.setContentType("application/json; charset=UTF-8");
httpServletResponse.getWriter().print("请携带token访问!");
return false;
}
// 验证 token
if (JwtUtil.verify(token, JwtUtil.getUsername(token))!=true){
throw new RuntimeException("token错误");
}
if (JwtUtil.isExpired(token)==true){
throw new RuntimeException("token过期");
}
//代表管理
if ("1".equals(tokenMethod.value())){
//为了方便此处使用username充当角色
String username = JwtUtil.getUsername(token);
if ("admin".equals(username)){
return true;
}
else {
throw new RuntimeException("权限不足无法访问!");
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
controller进行测试
@RestController
@RequestMapping("/jwt")
public class JwtController {
@PostMapping("/login")
public Object login(@RequestParam("userName") String userName) throws UnsupportedEncodingException {
String userId = UUID.randomUUID().toString();
// 生成签名
String token= JwtUtil.createToken(userName,1440000L);
Map userInfo = new HashMap<>();
userInfo.put("userId", userId);
userInfo.put("token", token);
return userInfo;
}
@Token("1")
@GetMapping("/getMessage")
public String getMessage(){
return "你已通过验证";
}
}
访问需求做验证的/jwt/getMessage方法
访问登陆方法返回token使用admin作为用户名
带token请求/jwt/getMessage



