개발/Spring(Hodol)

Spring - API 인증 (ArgumentResolver)

잇(IT) 2023. 10. 4. 15:52
728x90

- ArgumentResolver란 Spring MVC에서 사용되는 인터페이스로, 컨트롤러 메서드의 매개변수를 해석하고 해당 매개변수에 값을 제공하는 역할을 한다. 이를 통해 컨트롤러 메서드에서 다양한 매개변수 타입을 처리하고 커스텀한 바인딩 로직을 구현할 수 있다.

 

- HandlerMethodArgumentResolver 인터페에스를 상속 받고 다음과 같은 메서드를 정의한다.

 1. supportsParameter(MethodParameter parameter) : Resolver가 특정 매개변수를 지원하는지 여부를 판단하는 데 사용된다. MethodParameter 객체를 인자로 받고, 지원하는 매개변수인 경우 true를 반환하고, 그렇지 않은 경우, false를 반환해야 한다.

 2. resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) : 컨트롤러 메서드의 특정 매개변수에 값을 바인딩하는 로직을 정의한다. 이 메서드는 MethodParameter를 통해 매개변수의 정보를 받고, NativeWebRequest를 통해 현재 HTTP 요청 정보에 접근할 수 있다.


- PostController.java

@GetMapping("/test2")
    public String test2(UserSession userSession){
        log.info(">>> {}", userSession.name);
        return userSession.name;
    }

- UserSession을 매개변수로 받는 controller를 생성한다.

 

- UserSession.java

package com.islog.api.config.data;

public class UserSession {

    public String name;
}

- UserSession 클래스를 생성한다. UserSession 클래스에는 우선 name 인스턴스만 가지고 있다.

 

- AuthResolver.java

public class AuthResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(UserSession.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String accessToken = webRequest.getParameter("accessToken");
        if (accessToken == null || accessToken.equals("")) {
            throw new Unauthorized();
        }

        UserSession userSession = new UserSession();
        userSession.name = accessToken;
        return userSession;
    }
}
return parameter.getParameterType().equals(UserSession.class);

1. supportsParamter에서 해당 Controller의 메서드가 UserSession 클래스를 매개변수로 받는 컨트롤러 메서드를 지원하는지 여부를 판단하는데 사용된다.

@Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String accessToken = webRequest.getParameter("accessToken");
        if (accessToken == null || accessToken.equals("")) {
            throw new Unauthorized();
        }

        UserSession userSession = new UserSession();
        userSession.name = accessToken;
        return userSession;
    }

 

2.  UserSession 클래스가 매개변수에 존재하는 경우, AuthResolver의 resolveArgument 메서드가 실행되어 반환값을 해당 controller의 메서드에 전달한다.

3. 현재 /test2의 매개변수에 UserSession 클래스가 존재하기 때문에 supportsParameter의 검증에 의해 resolverArgument 메서드가 실행되고, 파라미터로 넘어온 accessToken 값이 넘어와 UserSession 객체의 name 값에 대입되고, 해당 객체를 반환하여 /test2 Controller 메서드에 전달한다.

- 정상적으로 쿼리 파라미터를 날린 경우 정상 응답이 온다.

- /test2의 요청 경로는 UseSession 클래스를 매개변수로 갖기 때문에 위에서 확인한 바와 같이 resolveArgument의 조건에 충족하지 않게 되면 예외를 발생 시키는 것을 확인 할 수 있다.


@GetMapping("/test3")
    public String test3(){
        return "인증이 필요없는 페이지";
    }

- 위와 같이 /test3 요청 경로의 경우 test3() 메서드의 매개변수로 아무것도 받지 않는다.

- 해당 경로로 요청이 들어오게 되면 supportsParameter에서 검증을 실행하게 되는데 UserSession 클래스를 가지고 있지 않기 때문에 검증이 필요하지 않은 요청 경로로 인식되어 resolveArgument 메서드가 실행되지 않는다.

- 때문에 위와 같이 /test3의 요청 경로는 별도의 인증을 하지 않아도 정상적으로 응답이 오는 것을 확인 할 수 있다.

728x90