세션에 있는 로그인정보 쉽게 사용하기(Spring, ArgumentResolver)

2023. 3. 29. 08:13개발

반응형

스프링부트

스프링을 잘 모르면서 개발하다보면 쉬운 방법들이 있는데 빙 돌아가는게 많구나..라는 생각을 항상 하게된다. ㅠㅠ

보통 session을 기반으로 하는 작은 서버의 경우 로그인시 session에 간략한 유저 정보를 담아 넣어두게 되는데..!

서버에서 간단하게 사용하려면 Util클래스를 만들어서 쉽게 session가져와서 해당 클래스에 넣어준다던가…아니면 필요한 정보만을 가져와서 사용한다던가 하는 형태로 만들어둔다.

예를들면 아래와 같은 형태. (SessionUtil클래스를 두고 Spring에서 원하는곳에서 HttpServletRequest에 접근 할 수 있게 만들어둔 RequestContextHolder를 사용하여 session을 컨트롤한다. 그리고 Util을 사용하는 다른클래스에서 Helper를 만들어서 객체를 넣어주고 빼고 사용하는는..?)

public class SessionUtil {

	public static void createSession(String name, Object value) {
		RequestContextHolder.getRequestAttributes().setAttribute(name, value, RequestAttributes.SCOPE_SESSION);
	}
	
	public static void removeSession(String name) {
		RequestContextHolder.getRequestAttributes().removeAttribute(name, RequestAttributes.SCOPE_SESSION);
	}

	
	public static Object getAttribute(String name) {
		return RequestContextHolder.getRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_SESSION);
	}
	
	public static boolean isSessionExist(String name) {
		return RequestContextHolder.getRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_SESSION) != null;
	}
}

그런데…!

ArgumentResolver를 사용하여 특정 어노테이션이 붙어있는 경우 session에 있는 객체를 집어넣어 주는형태로도 가능하였다!!

 

다른사람의 경우에는 꼭 session에 존재하는 값이 아니라 jwt와 같은 token값을 가공해서 넣어주는 형태로도 하더라..

여기 참고!

https://hudi.blog/spring-argument-resolver/

 

스프링에서 Argument Resolver 사용하기

컨트롤러에서 쿼리 스트링을 변수에 바인딩하려면 @RequestParam 을, 가변적인 경로를 변수에 바인딩하려면 @PathVariable 을, HTTP Body를 변수에 바인딩하려면 @RequestBody 를 사용해야한다. 하지만 HTTP Head

hudi.blog

 

방법은 다음과 같음.

구분을 위한 Login 어노테이션 생성.
(해당 어노테이션이 붙어있는 경우에는 session에 있는 값을 넣어줄거임)

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
}

 

LoginMemberArgumentResolver 클래스 (Argument Resolver 생성!)

@Slf4j
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        boolean hasLoginAnnotation = parameter.hasParameterAnnotation(Login.class);
        boolean hasMemberType = Member.class.isAssignableFrom(parameter.getParameterType());
        return hasLoginAnnotation && hasMemberType;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter
            , ModelAndViewContainer mavContainer
            , NativeWebRequest webRequest
            , WebDataBinderFactory binderFactory) throws Exception {
        return RequestContextHolder.getRequestAttributes().getAttribute(SessionConst.LOGIN_MEMBER, RequestAttributes.SCOPE_SESSION);
    }
}

supportsParameter의 조건이 충족되는 경우 아래 resolveArgument가 수행된다. (특정 클래스Type이면서 어노테이션이 붙은 경우에만 수행.)

resolveArgument의 경우에는 RequestContextHolder로 session에 접근하여 SessionConst.LOGIN_MEMBER 라는 이름으로 저장시킨 session값을 가져와서 return한다.

 

 

ArugmentResolver를 등록한다!

WebConfig 설정!

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new LoginMemberArgumentResolver());
    }
    
}

 

확인을 위해 사용 할 컨트롤러 모습.

@Slf4j
@Controller
public class TestController {

    @GetMapping("/test")
    public String test(@Login Member loginMember, Model model) {
            //세션에 회원 데이터가 없으면 home
            if (loginMember == null) {
                return "home";
            }
            //세션이 유지되면 로그인으로 이동
            model.addAttribute("member", loginMember);
            return "loginHome";
    }
}

이 경우

test라는 경로로 접근하게되면 loginMember에 session에 저장된 정보가 자동으로 들어간다!!

반응형