반응형
스프링부트를 통해 프로젝트를 진행하면 "Custom Annotation"을 통해 간편하게 로그인한 사용자의 정보를 불러올 수 있습니다.
Controller의 메서드는 사용자의 HTTP, HTTPS 요청을 Serivce에 전달하는 등 핵심 기능만 담당하고, 현재 로그인이 되어있는 사용자의 정보는 어노테이션을 통해 처리합니다.
로그인된 사용자의 정보 불러오기
HandlerMethodArgumentResolver 인터페이스를 구현한 클래스를 추가하여 컨트롤러에서 파라미터에 값을 바인딩 해줄 수 있습니다.
@PathVariable의 원리도 HandlerMethodArgumentHandler에 의해서 처리되는 것입니다.
1. 커스텀 어노테이션 정의하기
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
- @Target 부분에 이 어노테이션을 사용하는 범위를 지정합니다.
2. HandlerMethodArgumentResolver 구현하기
HandlerMethodArgumentResolver를 구현하여 커스텀 어노테이션을 처리할 로직을 작성합니다.
이를 통해 컨트롤러 메서드에서 @CurrentUser 어노테이션이 붙은 파라미터에 로그인 사용자 정보를 주입할 수 있습니다.
public class CurrentUserResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(CurrentUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String token = webRequest.getHeader("Authorization");
if (token == null) {
throw new ApiException(ErrorStatus._EMPTY_JWT);
}
return jwtProvider.getMemberFromToken(token.split(" ")[1]);
}
}
- supportsParameter() : 현재 parameter를 resolver가 지원할지 true/false로 반환합니다.
즉, 해당 메서드가 참이라면 resolveArgument()를 반환합니다.
false인 경우 아무 값도 반환받지 않습니다. - 해당 코드에서는 hasParameterAnnotation 메소드를 사용하여 해당 메서드에CurrentUser라는 어노테이션이 존재하는지 확인합니다.
- resolveArgument() : 실제 바인딩할 객체를 반환합니다.
- 해당 코드에서는 현재 로그인된 사용자의 JWT를 기준으로 로그인된 사용자의 정보로 Member 엔티티를 반환합니다.
3. Webconfig에 Resolver 등록하기
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final LoginUserArgumentResolver loginUserArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginUserArgumentResolver);
}
}
사용된 Controller 예시
@GetMapping()
public ApiResponse<CombinationResponse.CombinationPreviewResultList> getCombinations(
@Parameter(hidden = true) @MemberObject Member loginMember,
@CheckPage @RequestParam(name = "page") Integer page) {
return ApiResponse.onSuccess(
combinationQueryService.getCombinationPreviewResultList(page, loginMember));
}
반응형