Spring Security Oauth2 를 이용해 로그인을 할 경우, Principal를 이용해 name을 조회할 수 있는데, 여기서 한단계 더 나아가 유저정보를 가지고 있어야 할때가 있다.
이럴때 아마 principal.getName()을 이용해 유저정보를 조회한 후 회원정보를 불러올 것이다.
...
public String testUser(Principal principal) {
User findUser = loginMapper.findUserInfoByUserEmail(principal.getName());
...
}
...
아마 로그인을 이용한 정보는 거의 대부분의 비지니스 로직에서 쓸텐데 그렇다면 위 코드를 매번 삽입해야 한다. 이부분을 생략하고자 설정하는 것이다.
일전에 AOP를 이용해 어노테이션으로 설정, 조회하도록 했는데 매 메서드마다 어노테이션을 설정하는 것도 귀찮아 Resolver를 추가하게 되었다.
이전글:
그럼 이제 시작해보자.
우선 구현하는 방법은 파라미터 내용중 특정 클래스가 있으면 체크하도록 한다.
예를들어 이런 클래스를 추가한다.
@Getter
@ToString
@AllArgsConstructor
public class UserDto {
private Long userNo;
private String userEmail;
}
그리고 위 클래스가 등록된 Parameter의 경우만 가로채 데이터를 삽입한다. 다음같은 경우가 그렇다.
...
@GetMapping("/test/user/resolver")
@ResponseBody
public String testUserResolver(UserDto userDto) {
System.out.println("userDto = " + userDto);
return userDto.getUserEmail();
}
...
WebMvcConfigurer를 구현한 WebConfig 라는 파일을 만든다. 이 파일에서 Resolver를 등록할 수 있다.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final LoginMapper loginMapper;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CustomUserResolver(loginMapper));
}
}
addArgumentResolvers를 오버라이드 하여 구현한다. CustomUserResolver를 resolver에 추가등록한다.
LoginMapper 는 로그인을 조회하기 위한 Mapper 역할을 한다. JPA로 구성되어 있다면 Repository를 주입받으면 된다. 여기서 주입받는 이유는 CustomUserResolver에서 실질적으로 수행할건데, 해당 클래스는 빈으로 등록할 것이 아니기 때문이다.
그럼 이제 CustomUserResolver 구현체를 만든다.
public class CustomUserResolver implements HandlerMethodArgumentResolver {
private final LoginMapper loginMapper;
public CustomUserResolver(LoginMapper loginMapper) {
this.loginMapper = loginMapper;
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
// userDto 가 파라미터에 포함되어 있는지 체크하여 true를 리턴한다.
if(parameter.getParameterType() == UserDto.class){
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 인증된 정보를 가져와 getName() 을 호출한다. 여기서 호출은 principal.getName() 과 동일하다
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = authentication.getName();
// username 을 이용해 정보를 조회한다.(여기서는 email이 username 이다)
User findUser = loginMapper.findUserInfoByUserEmail(email);
// 조회한 정보를 UserDto에 담은 후 리턴한다
UserDto userDto = new UserDto(findUser.userNo(), findUser.getEmail());
return userDto;
}
}
이제 설정이 끝났다. 그럼 이전에 등록한 컨트롤러인 /test/user/resolver 를 호출한 후 로그를 확인해보자
...
@GetMapping("/test/user/resolver")
@ResponseBody
public String testUserResolver(UserDto userDto) {
System.out.println("userDto = " + userDto);
return userDto.getUserEmail();
}
...
userDto = userDto(userNo=1, userEmail=test@test.com)
의도한대로 잘 나온다.
끝.
'공부 > 프로그래밍' 카테고리의 다른 글
[jpa] 쿼리 로그 설정 (0) | 2021.01.15 |
---|---|
[axios, react, redux] 서버통신 시 로딩바 띄우기 (0) | 2021.01.13 |
[aws] aws cli로 s3 파일 삭제(console에서 파일삭제 실패 시-파일명 한글일 경우 실패함) (1) | 2021.01.08 |
[nginx] aws에 nginx설치 및 멀티도메인 설정(reverse-proxy) (0) | 2021.01.06 |
[airflow] BigQueryOperator 사용할때 location 에러 (0) | 2021.01.04 |
댓글