Springboot+jwt实现token校验
程序员文章站
2022-04-02 11:18:26
pom.xmlJwtInterceptor.javaJwtToken.javaJwtUtil.javaWebConfig.javaGlobalExceptionHandler.javapox.xml com.auth0 java-jwt .....
-
pom.xml
-
JwtInterceptor.java
-
JwtToken.java
-
JwtUtil.java
-
WebConfig.java
-
GlobalExceptionHandler.java
-
pox.xml
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.1</version>
</dependency>
- JwtInterceptor.java
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
// 从 http 请求头中取出 token
String token = httpServletRequest.getHeader("token");
// 如果不是映射到方法直接通过
if(!(object instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod=(HandlerMethod)object;
Method method=handlerMethod.getMethod();
//检查有没有需要用户权限的注解
if (method.isAnnotationPresent(JwtToken.class)) {
JwtToken jwtToken = method.getAnnotation(JwtToken.class);
if (jwtToken.required()) {
// 执行认证
if (token == null) {
throw new RuntimeException("无token,请重新登录");
}
// 获取 token 中的 userId
String userId = JwtUtil.getUserId(token);
System.out.println("用户id:" + userId);
// 验证 token
JwtUtil.checkSign(token);
}
}
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 {
}
}
- JwtToken.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JwtToken {
boolean required() default true;
}
- JwtUtil.java
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
public class JwtUtil {
/**
* 过期时间30分钟
*/
private static final long EXPIRE_TIME = 30 * 60 * 1000;
/**
* jwt 密钥
*/
private static final String SECRET = "jwt_secret";
/**
* 生成签名,30分钟后过期
* @param userId
* @return
*/
public static String sign(String userId) {
try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(SECRET);
return JWT.create()
// 将 user id 保存到 token 里面
.withAudience(userId)
// 30分钟后token过期
.withExpiresAt(date)
// token 的密钥
.sign(algorithm);
} catch (Exception e) {
return null;
}
}
/**
* 根据token获取userId
* @param token
* @return
*/
public static String getUserId(String token) {
try {
String userId = JWT.decode(token).getAudience().get(0);
return userId;
} catch (JWTDecodeException e) {
return null;
}
}
/**
* 校验token
* @param token
* @return
*/
public static boolean checkSign(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
// .withClaim("username", username)
.build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (JWTVerificationException exception) {
throw new RuntimeException("token 无效,请重新获取");
}
}
}
- WebConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 添加jwt拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
// 拦截所有请求,通过判断是否有 @JwtToken 注解 决定是否需要登录
.addPathPatterns("/**");
}
/**
* jwt拦截器
* @return
*/
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
- GlobalExceptionHandler.java
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.ArrayList;
import java.util.Set;
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
String msg = e.getMessage();
if (msg == null || msg.equals("")) {
msg = "服务器出错";
}
return Result.fail(msg);
}
}
注:Result参见上一篇Springboot配置validator参数校验
使用方法:
在需要进行token校验的接口添加@JwtToken即可
@JwtToken
@GetMapping("/test")
public void test() {
}
本文地址:https://blog.csdn.net/qq_24734285/article/details/109269394