개발 공부 기록
[SpringBoot] Interceptor 적용하기 본문
✔️ 인터셉터(Interceptor)란?
'가로챈다'라는 의미를 가진 인터셉터는 사용자의 요청을 가로채는 역할을 합니다. Spring 프레임워크에서 제공하는 기능 중 하나인 이 인터셉터는 Controller가 요청을 처리하기 전, 그리고 처리한 후에 추가적인 로직을 수행할 수 있도록 도와줍니다. 예를 들어 인터셉터가 요청에 대한 인증 및 권한 검사를 수행함으로써, 특정 요청이 처리되기 전에 사용자의 인증 상태를 확인할 수 있습니다.
✔️ 인터셉터 구현하기
HandlerInterceptor 인터페이스를 구현하며, 아래는 이 인터페이스를 구현하는데 사용될 수 있는 메서드입니다.
- preHandle() : 컨트롤러(핸들러)가 실행되기 전에 호출됩니다. 이 메서드에서는 true를 반환하여 컨트롤러 실행을 계속하거나, false를 반환하여 요청을 중단시킬 수 있습니다.
- postHandle() : 컨트롤러가 실행된 후, 뷰로 결과를 전달하기 전에 호출됩니다.
- afterCompletion() : 뷰의 실행까지 완료된 후 호출됩니다. 이때 리소스 정리나 예외 처리 등의 작업을 할 수 있습니다.
1. MemberInterceptor.java
@Slf4j
@RequiredArgsConstructor
@Component
public class MemberInterceptor implements HandlerInterceptor {
private final JwtTokenizer jwtTokenizer;
private final MemberRepository memberRepository;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//log.info("Request URI : " + request.getRequestURI());
String accessToken = jwtTokenizer.resolveToken(request);
String email = jwtTokenizer.extractEmailFromToken(accessToken);
validateUserExist(email);
return true;
}
private void validateUserExist(String email) {
if (isNotExistMember(email)) {
throw new CustomException(CustomResponseCode.MEMBER_NOT_FOUND);
}
}
private boolean isNotExistMember(String email) {
return !memberRepository.existsByEmail(email);
}
}
현재 사용자가 존재하는 사용자지 인증하는 부분입니다.
@Slf4j
@RequiredArgsConstructor
@Component
public class AdminInterceptor implements HandlerInterceptor {
private final JwtTokenizer jwtTokenizer;
private final MemberRepository memberRepository;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//log.info("Request URI : " + request.getRequestURI());
String accessToken = jwtTokenizer.resolveToken(request);
String email = jwtTokenizer.extractEmailFromToken(accessToken);
Member member = findMember(email);
if (hasNotRoleAdmin(member)) {
throw new CustomException(CustomResponseCode.ACCESS_DENIED_EXCEPTION);
}
return true;
}
private boolean hasNotRoleAdmin(Member member) {
return !member.hasRoleAdmin();
}
private Member findMember(String email) {
return memberRepository.findByEmail(email).orElseThrow(() -> new CustomException(CustomResponseCode.MEMBER_NOT_FOUND));
}
}
관리자만 접근할 수 있는 URI에 ADMIN이 아닌 MEMBER 권한을 가진 사용자가 접근했을 경우에 처리하는 부분입니다.
✔️ WebMvcConfig.java
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {
private final MemberInterceptor memberInterceptor;
private final AdminInterceptor adminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(memberInterceptor)
.order(1)
.excludePathPatterns("/api/signup/**")
.excludePathPatterns("/api/login")
.addPathPatterns("/api/**");
registry.addInterceptor(adminInterceptor)
.order(2)
.addPathPatterns("/api/admin/**");
}
}
addInterceptors 메서드를 오버라이딩하여 InterceptorRegistry를 통해 애플리케이션 내에 인터셉터를 등록할 수 있습니다. excludePathPatterns()를 사용하여 메서드의 인자로 전달하는 URI와 경로를 인터셉터 호출에서 제외시킬 수 있습니다. 반면, addPathPatterns()를 사용하여 인터셉터를 호출하는 URI와 경로를 추가할 수 있습니다.
'Spring > Development Log' 카테고리의 다른 글
[SpringBoot] SpringBoot에서 Redis 사용하기(2) (0) | 2023.12.31 |
---|---|
[SpringBoot] SpringBoot에서 Redis 사용하기(1) (1) | 2023.12.20 |
[SpringBoot] Argument Resolver을 통해 로그인한 유저 정보 가져오기 (0) | 2023.12.18 |
[SpringBoot] AccessDeniedHandler와 AuthenticationEntryPoint 구현 (0) | 2023.12.13 |
[Spring / JWT] Access Token과 Refresh Token (0) | 2023.12.09 |