下面我将为你详细讲解如何使用Spring Boot实现拦截器过滤Token并返回结果及异常处理操作。
什么是拦截器及Token认证
在Spring Boot中,拦截器是一种非常常用的组件,它可以拦截请求,进行一些处理,并执行相应的操作。Token认证是指在用户登录成功后,服务器会生成一个Token并返回给客户端,客户端在以后的请求中携带这个Token用于鉴权,服务器会验证Token的有效性以判断请求是否合法。
前置准备
在使用拦截器过滤Token之前,需要先引入相关的依赖。我们可以在pom.xml
文件中添加以下内容:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
其中,spring-boot-starter-web
是Spring Boot的Web相关依赖,jjwt
是JWT(Java Web Token)的Java实现库,用于Token的生成和校验。
实现拦截器过滤Token
为了实现拦截器过滤Token,我们需要创建一个实现HandlerInterceptor
接口的拦截器类,在该类中实现Token的验证和相应的处理逻辑。以下是一个简单的示例:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private TokenConfig tokenConfig;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
String token = request.getHeader("Authorization");
if (token == null) {
throw new ApiException("缺少AccessToken");
}
Claims claims = Jwts.parser().setSigningKey(tokenConfig.getSecretKey()).parseClaimsJws(token).getBody();
if (claims == null) {
throw new ApiException("无效AccessToken");
}
// TODO: 进行权限验证
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
其中,TokenConfig
是一个封装了Token认证相关配置内容的类;ApiException
是一个自定义异常类,用于统一处理异常并返回错误信息。在preHandle
方法中,我们首先对OPTIONS
请求进行处理,因为它是一个预检请求,不需要进行Token的验证。然后,我们从Authorization
请求头中获取Token,如果有Token,就使用jjwt
解析出其中的Claims
内容,并进行权限验证(这里我们只是简单地验证了Token是否有效),如果验证成功,就返回true
;否则,就抛出ApiException
异常并返回错误信息。
接下来,我们需要将该拦截器注册到Spring Boot的配置中,这可以通过WebMvcConfigurer
接口的实现类来实现。例如:
import org.springframework.beans.factory.annotation.Autowired;
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 {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor).addPathPatterns("/**");
}
}
在该类中,我们先注入了上面实现的拦截器类AuthInterceptor
,然后在addInterceptors
方法中将其添加到InterceptorRegistry
中,并配置需要拦截的路径。在这里,我们配置了所有请求都需要经过AuthInterceptor
的处理。
返回结果及异常处理操作
在拦截器中,我们可以通过抛出异常来处理请求过程中的错误。但是,在实际应用中,为了更好地返回错误信息并方便客户端处理,我们需要对异常进行统一的处理,以便将错误信息封装到接口响应体中返回给客户端。
以下是一个实现了接口响应统一格式的示例:
import lombok.Data;
@Data
public class ApiResponse<T> {
private Integer code;
private String message;
private T data;
public static <T> ApiResponse<T> ok(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage("OK");
response.setData(data);
return response;
}
public static <T> ApiResponse<T> error(Integer code, String message) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(code);
response.setMessage(message);
response.setData(null);
return response;
}
}
在该类中,我们定义了接口响应的统一格式,包括状态码、错误信息和响应数据。我们还添加了两个静态方法,用于构建成功和失败的接口响应。
在AuthInterceptor
中抛出异常时,我们可以在GlobalExceptionHandler
中对其进行捕获和处理,并返回相应的错误信息。以下是一个简单的实现示例:
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(ApiException.class)
public ApiResponse<Void> handleApiException(ApiException e) {
log.warn("请求发生异常: {}", e.getMessage());
return ApiResponse.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public ApiResponse<Void> handleException(Exception e) {
log.error("请求发生异常: ", e);
return ApiResponse.error(500, "服务内部错误,请稍后重试");
}
}
在该类中,我们定义了两个异常处理方法,一个是处理ApiException
异常,用于捕获AuthInterceptor
中抛出的异常并返回错误信息;另一个是处理Exception
异常,用于捕获其他未处理的异常,并返回服务内部错误的错误信息。
综合示例
以下是一个完整的示例,其中包含了基于Spring Boot的Token认证和拦截器过滤Token,并对Token认证异常进行了统一处理:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.example.demo.exception.ApiException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor).addPathPatterns("/**");
}
}
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private TokenConfig tokenConfig;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
String token = request.getHeader("Authorization");
if (token == null) {
throw new ApiException("缺少AccessToken");
}
Claims claims = Jwts.parser().setSigningKey(tokenConfig.getSecretKey()).parseClaimsJws(token).getBody();
if (claims == null) {
throw new ApiException("无效AccessToken");
}
// TODO: 进行权限验证
return true;
}
}
@Data
public class ApiResponse<T> {
private Integer code;
private String message;
private T data;
public static <T> ApiResponse<T> ok(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage("OK");
response.setData(data);
return response;
}
public static <T> ApiResponse<T> error(Integer code, String message) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(code);
response.setMessage(message);
response.setData(null);
return response;
}
}
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(ApiException.class)
public ApiResponse<Void> handleApiException(ApiException e) {
log.warn("请求发生异常: {}", e.getMessage());
return ApiResponse.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public ApiResponse<Void> handleException(Exception e) {
log.error("请求发生异常: ", e);
return ApiResponse.error(500, "服务内部错误,请稍后重试");
}
}
public class ApiException extends RuntimeException {
private Integer code;
public ApiException(String message) {
this(message, 400);
}
public ApiException(String message, Integer code) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
@ConfigurationProperties(prefix = "jwt")
@Data
public class TokenConfig {
private String secretKey;
private Long expireSeconds;
}
@RestController
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/test", method = RequestMethod.GET)
public ApiResponse<Void> test() {
return ApiResponse.ok(null);
}
}
在这个示例中,TokenConfig
和GlobalExceptionHandler
类分别用于配置Token认证和统一异常处理。我们在WebConfig
中将AuthInterceptor
注册到了Spring Boot的配置中,并配置其拦截所有请求。在ApiController
中,我们实现了一个简单的接口 test
,它用于测试接口的响应结果。
到这里,我们已经完成了基于Spring Boot的Token认证和拦截器过滤Token,并对Token认证异常进行了统一处理的实现。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot拦截器过滤token,并返回结果及异常处理操作 - Python技术站