Spring Boot – Login annotation 만들기

By | 2023년 2월 14일
Table of Contents

Spring Boot – Login annotation 만들기

로그인 체크를 하다보면 반복적으로 세션이나 쿠키에서 로그인 상태를 확인하고,
로그인 정보를 request.getAttribute 등으로 가져와야 하는 상황이 발생한다.

반복적 코드를 annotation 으로 만들어 파라미터로 즉시 받아오는 방식으로 수정할 수 있다.

기존 코드

@WebFilter("/admin/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        // 로그인 체크를 로그인 정보 DTO 생성

        httpServletRequest.setAttribute("loginInfo", loginInfo);

        chain.doFilter(httpServletRequest, httpServletResponse);
    }
}

모든 메소드에서 로그인 정보를 request.getAttribute 등으로 가져와야 하는 상황이 발생한다.

@Controller
@RequiredArgsConstructor
public class UserController {

    private final UserService service;

    @GetMapping("/admin/user/modify")
    public String modify(HttpServletRequest request, HttpServletResponse response, ModelMap model, @RequestParam(value = "id") Long userId) throws IOException {

        // 생성한 로그인 정보 DTO 페이지에 전달
        LoginInfoDto loginInfoDto = (LoginInfoDto) request.getAttribute("loginInfo");
        model.addAttribute("loginInfo", loginInfoDto);

        return "/admin/userModify";
    }

annotation 생성

LoginCheckFilter 는 그대로 사용합니다.

LoginInfo

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

LoginInfoArgumentResolver

로그인 정보를 HttpServletRequest 에 넣었으므로,
HttpServletRequest 에서 로그인 정보를 가져옵니다.

@RequiredArgsConstructor
@Component
public class LoginInfoArgumentResolver implements HandlerMethodArgumentResolver {

    private final HttpServletRequest httpServletRequest;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        boolean isLoginInfoAnnotation = parameter.getParameterAnnotation(LoginInfo.class) != null;
        boolean isLoginInfoClass = LoginInfoDto.class.equals(parameter.getParameterType());

        return isLoginInfoAnnotation && isLoginInfoClass;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return httpServletRequest.getAttribute("loginInfo");
    }
}

LoginConfig

@RequiredArgsConstructor
@Configuration
public class LoginConfig implements WebMvcConfigurer {

    private final LoginInfoArgumentResolver loginInfoArgumentResolver;

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

Controller

@LoginInfo 를 이용해 로그인 정보를 받습니다.

@RequiredArgsConstructor
@Controller
public class IndexController {

    // ......

    @GetMapping("/")
    public String index(Model model, @PageableDefault Pageable pageable, @LoginInfo LoginInfoDto user, @RequestParam Map<String, String> params) {
        // ......

        if (user != null) {
            model.addAttribute("userName", user.getName());
        }

        model.addAttribute("posts", postsPagingService.search(pageable, postsSearchDto));
        model.addAttribute("search", postsSearchDto);

        return "index";
    }

    // ......
}

답글 남기기