一、参考文档
SpringBoot集成JWT实现token验证 | 苍穹帝-CSDN
二、导入依赖pom.xml
<!-- jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
三、生成Token工具类TokenUtils
@Component
public class TokenUtils {
private static final long EXPIRE_TIME = 60 * 60 * 1000;
@Autowired
public static UserService staticUserService;
@Autowired
public UserService userService;
@PostConstruct
public void setUserService() {
staticUserService = userService;
}
public static String getToken(String userId, String sign) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
String token = "";
token = JWT.create().withAudience(userId)
.withExpiresAt(date)
.sign(Algorithm.HMAC256(sign));
return token;
}
public static User getCurrentUser() {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("token");
if (!StringUtils.isEmpty(token)) {
String userId = JWT.decode(token).getAudience().get(0);
return staticUserService.getById(Integer.valueOf(userId));
}
} catch (Exception e) {
return null;
}
return null;
}
}
四、拦截token拦截器JwtInterceptor
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
String token = httpServletRequest.getHeader("token");
if (!(object instanceof HandlerMethod)) {
return true;
}
if (StringUtils.isEmpty(token)) {
throw new MyException(ResultCodeEnum.TOKEN_ERROR);
}
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new MyException(ResultCodeEnum.TOKEN_CHECK_ERROR);
}
User user = userService.getById(userId);
if (user == null) {
throw new MyException(ResultCodeEnum.USER_NOT_EXISTS);
}
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new MyException(ResultCodeEnum.TOKEN_CHECK_ERROR);
}
return true;
}
}
五、拦截器配置InterceptorConfig
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(
"/user/login",
"/user/register"
);
}
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
六、配置全局异常捕获GlobalExceptionHandler和自定义异常处理MyException
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
e.printStackTrace();
return Result.fail();
}
@ExceptionHandler(MyException.class)
@ResponseBody
public Result error(MyException e) {
return Result.build(e.getCode(), e.getMessage());
}
}
@Data
public class MyException extends RuntimeException {
private Integer code;
public MyException(String message, Integer code) {
super(message);
this.code = code;
}
public MyException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
}
@Override
public String toString() {
return "YyghException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
七、状态信息枚举类ResultCodeEnum
@Getter
public enum ResultCodeEnum {
TOKEN_ERROR(400, "无token,请重新登录"),
TOKEN_CHECK_ERROR(401,"token验证失败,请重新登录"),
USER_NOT_EXISTS(402,"用户不存在,请重新登录"),
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
八、在login的SeviceImpl中生成token
@Override
public UserVo login(UserVo userVo) {
User one = getUserInfo(userVo);
if (one != null) {
BeanUtils.copyProperties(one, userVo);
String token = TokenUtils.getToken(one.getId().toString(), one.getPassword());
userVo.setToken(token);
return userVo;
} else {
throw new MyException(ResultCodeEnum.LOGIN_ERROR);
}
}
|