DevLog ๐Ÿ˜ถ

[Spring] ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ, ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ, ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋กœ๊ทธ์ธ ๊ฒ€์ฆํ•˜๊ธฐ ๋ณธ๋ฌธ

Back-end/Spring

[Spring] ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ, ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ, ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋กœ๊ทธ์ธ ๊ฒ€์ฆํ•˜๊ธฐ

dolmeng2 2022. 8. 28. 16:28

๊น€์˜ํ•œ ๋‹˜์˜ '์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ '์„ ๋ณด๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ๐Ÿ˜Š

 

์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MVC 2ํŽธ์—์„œ๋Š” MVC 1ํŽธ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ ๊ตฌ์กฐ ์œ„์— ์‹ค๋ฌด ์›น ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ํ™œ์šฉ ๊ธฐ์ˆ ๋“ค์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ

www.inflearn.com


์ง€๋‚œ ํฌ์ŠคํŒ…๊ณผ ์ด์–ด์ง‘๋‹ˆ๋‹ค :D

 

[Spring] ์ƒํ’ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ํšŒ์›๊ฐ€์ž… / ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ๋กœ์ง ์ถ”๊ฐ€ํ•˜๊ธฐ, ์ฟ ํ‚ค๋ฅผ ํ†ตํ•œ ์‹๋ณ„ ์ฒ˜๋ฆฌ

๊น€์˜ํ•œ ๋‹˜์˜ '์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ '์„ ๋ณด๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ๐Ÿ˜Š ์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„

cl8d.tistory.com


 

| ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ ์ ์šฉํ•˜๊ธฐ 

- ์ง€๋‚œ ํฌ์ŠคํŒ…๊นŒ์ง€ ์ง„ํ–‰ํ•œ ์ƒํ’ˆ ๊ด€๋ฆฌ ์›น ์‚ฌ์ดํŠธ๋Š” ์„ธ์…˜์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ์ด ๋งค์šฐ ์ž˜ ๋™์ž‘ํ•œ๋‹ค.

- ๊ทธ๋Ÿฌ๋‚˜, ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์ด๋”๋ผ๋„ 'URL'์„ ํ†ตํ•ด์„œ ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

- ์ด๋Ÿฌํ•œ '๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ'๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž.

 

๐Ÿšฉ HTTP ์š”์ฒญ -> WAS -> ํ•„ํ„ฐ -> ์„œ๋ธ”๋ฆฟ -> ์ปจํŠธ๋กค๋Ÿฌ

- ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜๋ฉด ํ•„ํ„ฐ ํ˜ธ์ถœ ํ›„ ์„œ๋ธ”๋ฆฟ์ด ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ํ•„ํ„ฐ์— ํŠน์ • URL ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํ•„ํ„ฐ์—์„œ ์š”์ฒญ์ด ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜๋ฉด ์„œ๋ธ”๋ฆฟ๊นŒ์ง€ ํ˜ธ์ถœ์„ ์•ˆ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค!

- ๋˜ํ•œ, ํ•„ํ„ฐ๋Š” ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค!

- โญ์ฐธ๊ณ ๋กœ, ํ•„ํ„ฐ์˜ ๊ฒฝ์šฐ ์ธํ„ฐ์…‰ํ„ฐ์™€ ๋‹ค๋ฅด๊ฒŒ ์•„์˜ˆ Spring Context์˜ ๋ฐ”๊นฅ๋ถ€๋ถ„์—์„œ ์‹คํ–‰๋œ๋‹ค!

 

โœ” Filter

- init() : ํ•„ํ„ฐ ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ. ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ์‹œ ํ˜ธ์ถœ

- doFilter() : ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ. ํ•„ํ„ฐ์˜ ์‹ค์งˆ์ ์ธ ๋กœ์ง ๊ตฌํ˜„๋ถ€.

- destroy() : ํ•„ํ„ฐ ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ. ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ์‹œ ํ˜ธ์ถœ.

 

[LoginCheckFilter.java]

- ๋กœ๊ทธ์ธ ์ธ์ฆ ํ•„ํ„ฐ ๊ตฌํ˜„ํ•˜๊ธฐ

public class LoginCheckFilter implements Filter {

    private static final String[] whiteList
            = {"/login/", "/login/members/add", "/login/members/login", "/login/members/logout", "/css/*"};

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String requestURI = httpRequest.getRequestURI();
        try {
            // whiteList ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ url์—์„œ ๊ฒ€์ฆ ์‹œ์ž‘
            if(!PatternMatchUtils.simpleMatch(whiteList, requestURI)) {
                HttpSession session = httpRequest.getSession(false);
                if(session == null || session.getAttribute("loginMember") == null) {
                    httpResponse.sendRedirect("/login/members/login?redirectURL="+ requestURI);
                    return; // ๋” ์ด์ƒ ์ง„ํ–‰ X
                }
            }
            // ๋‹ค์Œ ์ฒด์ธ์œผ๋กœ ์ด๋™ (์—†์œผ๋ฉด ์„œ๋ธ”๋ฆฟ์œผ๋กœ)
            chain.doFilter(request, response);
        } catch (Exception e) {
            throw e;
        }
    }

}

- ๋ฉ”์ธ ํ™”๋ฉด, ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… ํ™”๋ฉด์—์„œ๋Š” ๋กœ๊ทธ์ธ์ด ์•ˆ ๋˜์–ด ์žˆ์–ด๋„ ๋ณด์—ฌ์ ธ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— whiteList์— ์ถ”๊ฐ€ํ•˜์˜€๋‹ค.

- ๋งŒ์•ฝ session์ด ์—†๊ฑฐ๋‚˜, session ๋‚ด๋ถ€์— loginMember ๊ฐ์ฒด๊ฐ€ ์—†์œผ๋ฉด ๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•œ๋‹ค.

- โญ ์ด๋•Œ, httpResponse.sendRedirect("") ์‹œ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ redirectURL์„ ๋„ฃ์–ด์ฃผ์–ด์„œ, ๋กœ๊ทธ์ธ ์ดํ›„ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ์ ‘์†ํ–ˆ๋˜ ํŽ˜์ด์ง€๋กœ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•จ๊ป˜ ๋ณด๋‚ด์ค€๋‹ค! (๋ฌผ๋ก  ๋”ฐ๋กœ ์ด์— ๋Œ€ํ•ด์„œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค) 

- ๋˜ํ•œ, return;์„ ๊ฑธ์–ด์ฃผ์–ด์„œ ๋” ์ด์ƒ ์ง„ํ–‰๋˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค. (๋ฌผ๋ก  ํ•˜์œ„ chain.doFilter๋ฅผ else ๋ฌธ์œผ๋กœ ๊ฑธ์–ด๋„ ๋™์ผํ•˜๊ธด ํ•˜์ง€๋งŒ ์ด๊ฒŒ ๋” ๊น”๋”ํ•˜๋‹ค)

 

[WebMvcConfig.java] 

@Bean
public FilterRegistrationBean loginCheckFilter() {
    FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
    filterRegistrationBean.setFilter(new LoginCheckFilter());
    filterRegistrationBean.setOrder(1);
    filterRegistrationBean.addUrlPatterns("/*");
    return filterRegistrationBean;
}

- ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด์„œ ํ•„ํ„ฐ๊ฐ€ ์ ์šฉ๋˜๋„๋ก /*๋กœ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜๊ณ , ์ˆœ์„œ ์—ญ์‹œ ๊ฐ€์žฅ ๋จผ์ € ์ง„ํ–‰ํ•ด์ฃผ์—ˆ๋‹ค.

(๊ฐ•์˜์—์„œ๋Š” ๋กœ๊ทธ ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ–ˆ์ง€๋งŒ, ๋กœ๊ทธ๋Š” ๋‚˜์ค‘์— AOP๋ฅผ ํ†ตํ•ด ์„ค์ •ํ•˜๋Š” ๊ฒŒ ๋‚˜์„ ๊ฒƒ ๊ฐ™์•„์„œ)

 

[LMemberController.java]

@PostMapping("/login")
public String login(@Valid @ModelAttribute("loginForm") LMemberLoginRequest loginRequest,
                    @RequestParam(defaultValue = "/login/") String redirectURL,
                    BindingResult bindingResult, HttpServletRequest request) {
    if(bindingResult.hasErrors()) {
        return "login/members/loginForm";
    }

    LMember loginMember = service.login(loginRequest);
    if(loginMember == null) {
        bindingResult.reject("loginFail", "์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        return "login/members/loginForm";
    }

    HttpSession session = request.getSession();
    session.setAttribute("loginMember", loginMember);
    return "redirect:" + redirectURL;
}

- ํ•„ํ„ฐ์—์„œ ๋ณด๋‚ธ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ(redirectURL) ๊ฐ’์„ ๋ฐ›์•„์„œ ๋กœ๊ทธ์ธ ์‹œ ํ•ด๋‹น url๋กœ ๋„˜์–ด๊ฐ€๋„๋ก ์ง„ํ–‰ํ•ด์ค€๋‹ค.

- ๋ฌผ๋ก , ๊ทธ๋ƒฅ ๋ฐ”๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์ด ์—†์„ ํ…Œ๋‹ˆ defaultValue์ธ /login/๋กœ ์„ค์ •๋˜์–ด ํ™ˆ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•œ๋‹ค.


| ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ

๐Ÿšฉ HTTP ์š”์ฒญ -> WAS -> ํ•„ํ„ฐ -> ์„œ๋ธ”๋ฆฟ  -> ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ -> ์ปจํŠธ๋กค๋Ÿฌ

- ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์„œ๋ธ”๋ฆฟ๊ณผ(์Šคํ”„๋ง์—์„œ๋Š” DispatcherServlet) ์ปจํŠธ๋กค๋Ÿฌ ์‚ฌ์ด์—์„œ ํ˜ธ์ถœ๋œ๋‹ค.

- ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ด ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜๋ฉด ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์ธํ„ฐ์…‰ํ„ฐ์—์„œ ๋์„ ๋‚ธ๋‹ค.

- ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž์œ ๋กญ๊ฒŒ ์ธํ„ฐ์…‰ํ„ฐ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- ์ธํ„ฐ์…‰ํ„ฐ ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” HandlerInterceptor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

    -โญ preHandle (์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ „), postHandler (์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ํ›„), afterCompletion(์š”์ฒญ ์™„๋ฃŒ ์ดํ›„)

- ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋Š” HttpServletRequest/Response๋งŒ ์ œ๊ณตํ•˜์ง€๋งŒ, ์ธํ„ฐ์…‰ํ„ฐ๋Š” Handler ์ •๋ณด๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

    - ๋˜ํ•œ, ์ถ”๊ฐ€์ ์œผ๋กœ ModelAndView๋‚˜ Exception ์ •๋ณด๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค!

 

โœ” ์ฝ”๋“œ ํ™•์ธ

public interface HandlerInterceptor {
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}
    
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}
}

- postHandle์—์„œ๋Š” ModelAndView๋ฅผ, afterCompletion์—์„œ๋Š” Exception ์ •๋ณด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ“‘ cf) ํ•„ํ„ฐ์™€ ์ธํ„ฐ์…‰ํ„ฐ์˜ ์ฐจ์ด๋Š” ๋‹ค์Œ ๋ธ”๋กœ๊ทธ์— ์ •๋ง ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ๋‹ค...!

 

[Spring] ํ•„ํ„ฐ(Filter) vs ์ธํ„ฐ์…‰ํ„ฐ(Interceptor) ์ฐจ์ด ๋ฐ ์šฉ๋„ - (1)

Spring์€ ๊ณตํ†ต์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ ์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์„ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ๊ทธ ์ค‘์—์„œ ํ•„ํ„ฐ(Filter) vs ์ธํ„ฐ์…‰ํ„ฐ(Interceptor)์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž

mangkyu.tistory.com

 

โœ” ํ˜ธ์ถœ ํ๋ฆ„

- ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ -> Dispatcher Servlet

-> preHandle() ํ˜ธ์ถœ -- (true ๋ฐ˜ํ™˜) // false๋ผ๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„ ์ง„ํ–‰ X

--> ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ

-> ํ•ธ๋“ค๋Ÿฌ -- (ModelAndView ๋ฐ˜ํ™˜)

-> ๋ฐ›์•˜๋˜ modelAndView, ๊ทธ๋ฆฌ๊ณ  ํ•ธ๋“ค๋Ÿฌ ์ •๋ณด์™€ ํ•จ๊ป˜ postHandle() ํ˜ธ์ถœ  

-> view๋ฅผ ํ†ตํ•œ ๋ Œ๋”๋ง ์ง„ํ–‰ (render(model))

-> afterCompletion() ํ˜ธ์ถœ

 

โœ” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ

- ์š”์ฒญ -> Dispatcher Servlet

-> preHandle() ํ˜ธ์ถœ -- (true ๋ฐ˜ํ™˜) // false๋ผ๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„ ์ง„ํ–‰ X

--> ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ

-> ํ•ธ๋“ค๋Ÿฌ -- ์˜ˆ์™ธ ๋ฐœ์ƒ

-> ๋‹ค์‹œ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋กœ ๋Œ์•„์˜ค๋ฉด์„œ ์˜ˆ์™ธ๊ฐ€ ํ•จ๊ป˜ ์ „๋‹ฌ

-> ์ด๋•Œ, Dispatcher Servlet์— ์˜ˆ์™ธ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด postHandle ํ˜ธ์ถœ X

-> afterCompletion ํ˜ธ์ถœ (์˜ˆ์™ธ ์œ ๋ฌด๋ž‘ ์ƒ๊ด€ X) -- ๊ทธ๋ž˜์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ๋ฐ›์•„์„œ ์ถœ๋ ฅ ๊ฐ€๋Šฅ

 

์ธํ„ฐ์…‰ํ„ฐ๋Š” addPathPatterns, excludePathPatterns์œผ๋กœ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ๋“ฑ๋กํ•  ํŒจํ„ด, ์ œ์™ธํ•  ํŒจํ„ด์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํ•„ํ„ฐ๋Š” addUrlPatterns์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ค„ ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, ์ด๋•Œ ํŒจํ„ด์„ ๋“ฑ๋กํ•˜๋Š” ๊ทœ์น™ ์—ญ์‹œ ๋‹ค๋ฅด๋‹ค.

 

ํ•„ํ„ฐ๋Š” ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜์—ฌ ๊ณตํ†ต์ ์œผ๋กœ ๊ฐ’์„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์š”์ฒญ๋งˆ๋‹ค ์ ์šฉ๋˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง€์—ญ๋ณ€์ˆ˜ ์‚ฌ์šฉ์ด ์•ˆ ๋œ๋‹ค.

- ๊ทธ๋ž˜์„œ preHandle <=> postHandle ๋“ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋Š” request.setAttribute / getAttribute๋ฅผ ํ†ตํ•ด ์š”์ฒญ์— ๋„ฃ์–ด๋‘๊ณ  ์„œ๋กœ ์ ‘๊ทผํ•˜๋ฉด ๋œ๋‹ค.

 

[LoginCheckInterceptor.java]

public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        HttpSession session = request.getSession(false);
        if(session == null || session.getAttribute("loginMember") == null) {
            response.sendRedirect("/login/members/login?redirectURL="+ requestURI);
            return false;
        }
        return true;
    }
}

- ํ•„ํ„ฐ์™€ ๋‹ค๋ฅด๊ฒŒ whiteList ๊ฒ€์ฆ ๊ฐ™์€ ๊ฑธ ์ธํ„ฐ์…‰ํ„ฐ ๋‹จ์œ„์—์„œ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

- ๋‚˜์ค‘์— ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ์ด์— ๋Œ€ํ•ด ์ ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

- ๋กœ๊ทธ์ธ์€ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ์ด ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ํ•ด์•ผ ๋˜๋Š” ๊ฒƒ์ด๋‹ˆ๊นŒ preHandle๋งŒ ๊ตฌํ˜„ํ•ด์ค€๋‹ค.

 

[WebMvcConfig.java]

@Override
public void addInterceptors(InterceptorRegistry registry) {
    ...
    registry.addInterceptor(new LoginCheckInterceptor())
            .addPathPatterns("/login", "/basic/items")
            .excludePathPatterns("/login/", "/login/members/add", 
                    "/login/members/login", "/login/members/logout", "/css/*");
}

- ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. excludePathPattern์— whiteList์— ์žˆ๋˜ ๊ฒฝ๋กœ๋“ค์„ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 


| ArgumentResolver๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ํ™•์ธ ๊ธฐ๋Šฅ

[Login.java] - ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜

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

[LoginMemberArgumentResolver.java]

public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        boolean hasParameterAnnotation = parameter.hasParameterAnnotation(Login.class);
        boolean hasMemberType = LMember.class.isAssignableFrom(parameter.getParameterType());
        return hasParameterAnnotation && hasMemberType;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) webRequest;
        HttpSession session = request.getSession(false);
        if(session == null) {
            return null;
        }
        return session.getAttribute("loginMember");
    }
}

- ๋งŒ๋“ค์–ด์ค€ ์–ด๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•œ ๋ฆฌ์กธ๋ฒ„๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

- supportParameter๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋ถ™์€ ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ์–ด๋…ธํ…Œ์ด์…˜์— ๋ถ™์€ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•œ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•˜๊ณ ,

resolveArgument๋Š” ์‹ค์งˆ์ ์œผ๋กœ ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ์ฒ˜๋ฆฌํ•  ์ผ์„ ๋ช…์‹œํ•ด์ค€๋‹ค. (๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ทธ๋ƒฅ ์„ธ์…˜ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•œ๋‹ค) 

 

[LHomeController.java]

@Controller
@RequiredArgsConstructor
@RequestMapping("/login")
public class LHomeController {
    @GetMapping("/")
    public String home(
            @Login LMember loginMember,
            Model model) {

        if (loginMember == null) {
            return "login/home";
        }
        model.addAttribute("member", loginMember);
        return "login/loginHome";
    }
}

- ๋งŒ๋“ค์–ด์ค€ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ปจํŠธ๋กค๋Ÿฌ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋ถ™์˜€๋‹ค.

- ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ฝ”๋“œ๊ฐ€ ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ•ด์ง€๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

- ์ด๋Ÿฌ๋ฉด ํ•ด๋‹น loginMember์˜ ํƒ€์ž…์ด LMemberํ˜•์ด๋ผ๋ฉด ์„ธ์…˜์—์„œ "loginMember"์˜ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ loginMember์— ๋„ฃ์–ด์ค€๋‹ค.

 

[WebMvcConfig.java]

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

- ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ค์–ด์ค€ argumentResolver๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.- ์ด๋ ‡๊ฒŒ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ•ด๋ณด์•˜๋‹ค.

 

- ๋‹ค์Œ์—๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐ ์˜ค๋ฅ˜ ํŽ˜์ด์ง€ ์ƒ์„ฑ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.

Comments