쿠키 검증로직까지 만들었다면 한가지 난감한 상황이 생긴다.
로그인을 할때도 토큰검증을 해버린다는것..
Interceptor는 별다른 처리가 없을때는 전체 API를 대상으로 동작하기 때문에 이런경우는 제외시켜주어야 한다.
이를 Custom Annotation으로 해결해보겠다.
ExcludeAuth
/* 인증예외 어노테이션 생성 (AuthIntercepter에서 예외처리) */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcludeAuth {
}
ExcludeAuth라는 이름의 annotation을 만들어줬다.
TokenAuthInterceptor
@Slf4j
@Component
public class TokenAuthInterceptor implements HandlerInterceptor {
public static final String USER_ID = "X-USER-ID";
private final JwtProvider jwtProvider;
public TokenAuthInterceptor(JwtProvider jwtProvider) {
this.jwtProvider = jwtProvider;
}
/**
* 컨트롤러에 도착하기 직전 정보를 반환한다.
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//어노테이션 체크 - Controller에 @ExcludeAuth 어노테이션이 있는지 확인
boolean hasAnnotation = hasAnnotation(handler, ExcludeAuth.class);
try {
if (!hasAnnotation) {
JwtTokenDto tokenUser = jwtProvider.checkAccessToken(request);
request.setAttribute("cIdx", tokenUser.getCIdx());
request.setAttribute("uIdx", tokenUser.getUIdx());
request.setAttribute("uId", tokenUser.getUId());
MDC.put(USER_ID, tokenUser.getUId()); // 로그 출력시에 USER_ID값을 사용할 수 있도록 저장한다.
} else {
log.debug("Access Token 인증 제외");
}
} catch (Exception e) {
throw new BadRequestException(ServerResponse.EXPIRE_TOKEN);
}
return true;
}
public <A extends Annotation> boolean hasAnnotation(Object handler, Class<A> annotationClass) {
if (handler instanceof HandlerMethod handlerMethod) {
// 메서드에 어노테이션이 있는지 확인
return handlerMethod.getMethodAnnotation(annotationClass) != null;
}
return false; // 어노테이션이 없을 경우
}
}
TokenAuthInterceptor에서도 로직을 추가해준다.
hasAnnotation는 handler에 특정한 annotationClass가 존재하는지 판별하는 함수이다.
ExcludeAuth.class가 없을때는 기본으로 token을 검사하게 된다.
token을 검사하지 않을때는 로그에 생략되었다고 남겼다.
적용
@ExcludeAuth // !! 추가된 부분 !!
@PostMapping("/login")
public ResponseEntity<ServerResponse> login(HttpServletRequest request, @RequestBody AuthLoginRequest param, HttpServletResponse response) {
log.debug("Controller [{}] 진입", Thread.currentThread().getStackTrace()[1].getMethodName());
JwtTokenDto user = authService.login(request, param);
// 로그인 토큰 생성
jwtProvider.createAccessTokenString(user, response);
return ResponseEntity.ok(ServerResponse.SUCCESS);
}
Controller에서 Token 검증을 제외하고싶은 함수부분에 @ExcludeAuth을 추가하면 Token검사에서 제외된다.
테스트
토큰 없이도 정상로그인이 되는것이 확인된다.
'Back-End > JAVA' 카테고리의 다른 글
Spring 프로젝트 시작하기 - 로그인편 (2) | 2024.11.19 |
---|---|
Spring 프로젝트 시작하기 - 보안 ) Access Token과 Refresh Token (1) | 2024.11.18 |
Spring 프로젝트 시작하기 - 보안 ) Jwt Token 쿠키 검증 (0) | 2024.11.15 |
Spring 프로젝트 시작하기 - 보안 ) Jwt Token 쿠키 발급 (1) | 2024.11.14 |
Spring 프로젝트 시작하기 - 예외처리편 (0) | 2024.11.13 |