记录一次JWT &拦截器学习
记录一次JWT &拦截器学习
看阮一峰的博客JSON Web Token 入门教程
成功
引入jwt依赖和拦截器依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
controller.java类
@RestController
@RequestMapping("user")
public class UserLoginController {
@Value("${Login.username}")
private String realUsername;
@Value("${Login.password}")
private String realPassword;
@GetMapping("login")
public String login(String username, String password) {
if (username.equals(realUsername) && password.equals(realPassword)) {
User u = new User();
u.setPassword(password);
u.setUsername(username);
return JWTUtils.getToken(u);
}
return "登录失败!账号或者密码不对!";
}
@GetMapping("test")
public String test() {
return "访问test - API";
}
}
实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@NotNull(message = "id不能为空")
private Integer id;
@NotBlank(message = "姓名不能为空")
@Length(min = 2, max = 4, message = "name 姓名长度必须在 {min} - {max} 之间")
private String username;
@NotBlank(message = "密码不能为空")
@Length(min = 5, max = 10, message = "password 密码长度必须在 {min} - {max} 之间")
private String password;
}
拦截器
@Configuration
public class IntercaptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
//拦截的路径
.addPathPatterns("/**")
//排除登录接口
.excludePathPatterns("/user/login");
}
}
JWT拦截器
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {
private com.example.easyjwt.utils.JWTUtils JWTUtils;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("token");
try {
JWTUtils.verify(token);
} catch (SignatureVerificationException e) {
log.error("无效签名! 错误 ->", e);
return false;
} catch (TokenExpiredException e) {
log.error("token过期! 错误 ->", e);
return false;
} catch (AlgorithmMismatchException e) {
log.error("token算法不一致! 错误 ->", e);
return false;
} catch (Exception e) {
log.error("token无效! 错误 ->", e);
return false;
}
return true;
}
}
工具类JWT
public class JWTUtils {
/**
* 获取token
*
* @param u user
* @return token
*/
public static String getToken(User u) {
Calendar instance = Calendar.getInstance();
//默认令牌过期时间7天
instance.add(Calendar.DATE, 7);
JWTCreator.Builder builder = JWT.create();
builder.withClaim("userId", u.getId())
.withClaim("username", u.getUsername());
return builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(u.getPassword()));
}
/**
* 验证token合法性 成功返回token
*/
public static DecodedJWT verify(String token) {
//获取登录用户真正的密码假如数据库查出来的是123456
String password = "admin";
JWTVerifier build = JWT.require(Algorithm.HMAC256(password)).build();
return build.verify(token);
}
}
拦截器的原理就是,在调用controller之前执行