[스프링부트]5.4 구글 로그인 테스트 & 어노테이션 기반으로 개선하기

Bummy·2022년 8월 31일
0

springboot

목록 보기
12/15

구글 로그인 테스트

프로젝트를 실행해서 구글 로그인 테스트를 진행한다.

어플리케이션을 실행시켜서 확인해보면 다음과 같이 구글 로그인 탭이 생긴 것을 확인할 수 있다.

로그인이 성공하면 구글 계정에 등록된 이름이 화면에 노출되는 것을 확인할 수 있다.

h2-console에 들어가보면

다음과 같이 로그인한 유저의 정보가 정상적으로 담겨 있는 것을 확인할 수 있다.


어노테이션 기반으로 개선하기

프로그래밍에서 개선이 필요한 코드는 반복되는 코드이다. 코드가 반복되면 개발하기에도 어려움이 있고 이후에 유지보수에도 여러 곳을 반복해서 수정해야하는 여러 문제가 발생하기에 여러번 반복되는 코드는 수정이 필요하다.

앞서 만든 코드에서 개선해야하는 부분은 IndexController에서 세션값을 가져오는 부분이다.

SessionUser user = (SessionUser) httpSession.getAtrribute("user");

index 메소드 외에 다른 컨트롤러와 메소드에서 세션값이 필요하면 다음 코드를 작성해서 직접 세션에서 값을 가져와야한다. 이 부분을 메소드 인자로 세션값을 바로 받을 수 있도록 할 것이다.

LoginUser

@Target(ElementType.PARAMETER) //이 어노테이션이 생성될 수 있는 위치를 지정, 파라미터로 지정했으니 메소드의 파라미터로 선언된 객체에서만 사용할 수 있다.
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {//이 파일을 어노테이션 클래스로 지정, LoginUser라는 이름을 가진 어노테이션이 생성됨
}
  • @Target(ElementType.PARAMETER) : 이 어노테이션이 생성될 수 있는 위치를 지정, PARAMETER로 지정했으니 메소드의 파라미터로 선언된 객체에서만 사용할 수 있다.
    이 외에도 클래스 선언문에 쓸 수 있는 TYPE등이 있다.
  • @interface : 이 파일을 어노테이션 클래스로 지정, LoginUser라는 이름을 가진 어노테이션이 생성되었다고 보면 된다.

LoginUserArgumentResolver

@RequiredArgsConstructor
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
    private final HttpSession httpSession;

    @Override
    public boolean supportsParameter(MethodParameter parameter){ //supportsParameter : 컨트롤러 메소드의 특정 파라미터를 지원하는지 파악
        boolean isLoginUserAnnotation = parameter.getParameterAnnotation(LoginUser.class) != null;
        boolean isUserClass = SessionUser.class.equals(parameter.getParameterType());
        return isLoginUserAnnotation && isUserClass;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,  //resolveArgument: 파라미터에 전달할 객체를 생성, 여기서는 세션에서 객체를 가져옴
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception{
        return httpSession.getAttribute("user");
    }
}
  • supportsParameter() : 컨트롤러 메소드의 특정 파라미터를 지원하는지 판단, 여기서는 파라미터에 @LoginUser 어노테이션이 붙어 있고, 파라미터 클래스 타입이 SessionUser.class인 경우 true를 반환
  • resolveArgument() : 파라미터에 전달할 객체를 생성, 여기서는 세션에서 객체를 가져온다.

생성한 LoginUserArgumentResolver가 스프링에서 인식 될 수 있도록 WebMvcConfig에 추가한다.
WebConfig

@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
    private final LoginUserArgumentResolver loginUserArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
        argumentResolvers.add(loginUserArgumentResolver);
    }
}

-> HandlerMethodArgumentResolver는 항상 WebMvcConfiguser의 addArgumentResolver()를 통해 추가해야하며 다른 HandlerMethodArgumentResolver가 필요하다면 같은 방식으로 추가해주면 된다.


모두 수정되었으니 IndexController의 코드에서 반복되는 부분들을 모두 @LoginUser로 개선해주면된다.

IndexController

@RequiredArgsConstructor
@Controller
public class IndexController {

    private final PostsService postsService;
    private final HttpSession httpSession;
    @GetMapping("/")
    public String index(Model model, @LoginUser SessionUser user){ //Model: 서버 템플릿 엔진에서 사용할 수 있는 객체를 저장할 수 있다.
        //여기서는 postsService.findAllDesc()로 가져온 결과를 posts로 index.mustache에 전달한다.
        //@LoginUser SessionUser user : rlwhsdp httpSession.getAttribute("user")로 가져오던 세션 정보 값이 개선됨
        model.addAttribute("posts", postsService.findAllDesc());
        if(user != null){
            model.addAttribute("userName", user.getName());
        }
        return "index";
    }

    @GetMapping("/posts/save")
    public String postsSave(){
        return "posts-save";
    }

    @GetMapping("/posts/update/{id}")
    public String postsUpdate(@PathVariable Long id, Model model){
        PostsReponseDto dto = postsService.findById(id);
        model.addAttribute("post", dto);

        return "posts-update";
    }
}
  • @LoginUser SessionUser user : 기존에 httpSession.getAttribute("user")로 가져오던 세션 정보 값이 개선, 이제는 어느 컨트롤러든지 @LoginUser만 사용하면 세션 정보를 가져올 수 있게 되었다.

0개의 댓글