개인 프로젝트에서 인증 구현에 대한 내용을 서술한다.
인터셉터를 사용하기 위해서 HandlerIntercepor 인터페이스를 구현해야 한다.
HandlerIntercepor에는 3가지 메서드를 오버라이딩 할 수 있다.
이 중 컨트롤러 진입 이전에 토큰의 유효성 검사 및 사용자 인증을 진행해야하기 때문에 preHandle() 메서드를 구현했다.
@Component
public class AuthInterceptor implements HandlerInterceptor {
private static final String BEARER = "Bearer ";
private final AuthService authService;
public AuthInterceptor(AuthService authService) {
this.authService = authService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.hasMethodAnnotation(Authenticated.class)) {
String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
checkHeader(authorizationHeader);
String token = authorizationHeader.substring(BEARER.length());
verifyToken(token);
}
return true;
}
//...
}
preHandle()의 구현 내용을 살펴보면
먼저 Handler가 @Authenticated를 가지고 있는지 확인을 한다.
이후 Http AUTHORIZATION 헤더에서 값을 가져온 뒤
checkHeader() 메서드를 통해 헤더의 유효성 검사를 진행하고
헤더의 토큰을 추출한 뒤
verifyToken() 메서드를 통해 토큰의 유효성 검사를 진행한다.
ArgumentResolver를 사용하기 위해서 HandlerMethodArgumentResolver 인터페이스를 구현 해야 한다.
HandlerMethodArgumentResolver에는 2가지 메서드를 오버라이딩 할 수 있다.
@Component
public class OwnerArgumentResolver implements HandlerMethodArgumentResolver {
private static final String BEARER = "Bearer ";
private final AuthService authService;
public OwnerArgumentResolver(AuthService authService) {
this.authService = authService;
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(String.class)
&& parameter.hasParameterAnnotation(OwnerIdentifier.class);
}
@Override
public String resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
String authorizationHeader = webRequest.getHeader(HttpHeaders.AUTHORIZATION);
checkHeader(authorizationHeader);
String token = authorizationHeader.substring(BEARER.length());
return authService.findIdentifierByToken(token);
}
//...
}
resolverArgument의 구현 내용을 살펴보면
Http AUTHORIZATION 헤더에서 값을 가져온 후
checkHeader() 메서드를 통해 헤더의 유효성 검사를 진행하고
헤더의 토큰을 추출한 후
토큰을 사용해 가게 주인의 아이디를 조회하여 반환하는 로직을 가지고 있다.
supprotParameer의 구현 내용을 살펴보면
parameter의 타입이 String인지 And
parameter가 OwnerIdentifier 어노테이션을 가지고 있는지를 판단하는 로직을 가지고 있다.