저번에는 사용자가 로그인 한 다음에 특정 값을 Session에 저장하여 로그인상태를 유지했다.
지금부터는 Servlet이 제공하는 Filter, Spring이 제공하는 Interceptor에 대해서 알아보고, 적용해보겠다.
Filter
- Servlet이 제공하는 기능으로, WAS와 Servlet사이에서 공통관심사를 처리하기 위한 기능이다.
- Chain으로 구성되며, 중간에 필터를 자유롭게 추가할 수 있다.
- 필터 인터페이스를 구현하고 등록하면 서블릿 컨테이너가 필터를 싱글톤 객체로 생성하고, 관리한다
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException{}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
- init(): 필터 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출된다.
- doFilter(): 고객의 요청이 올 때 마다 해당 메서드가 호출된다. 필터의 로직을 구현하면 된다.
- destroy(): 필터 종료 메서드, 서블릿 컨테이너가 종료될 때 호출된다.
1.SessionFilter.java를 생성한다.
경로(\src\main\java\com\project\web\session\SessionFilter.java)
package com.project.web.session;
import com.project.domain.session.SessionConst;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.PatternMatchUtils;
import java.io.IOException;
public class SessionFilter implements Filter {
//SessionFilter에서 예외되는 Path들이다.
private static final String[] excludePath = {"/", "/sign/*", "/assets/*", "/images/*"};
@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(); //요청한 URI, SessionFilter이후에 redirect시키기위해 변수선언.
try {
//SessionFilter 예외처리 되지 않은 Path라면
if (!isExclude(requestURI)) {
//세션을 불러온다.
HttpSession session = httpRequest.getSession();
//세션이 null이거나, 세션에 로그인정보가 없다면 로그인화면으로 redirect시킨다.
if (session == null || session.getAttribute(SessionConst.SESSION_NAME) == null) {
httpResponse.sendRedirect("/sign/signIn?redirectUrl=" + requestURI);
return;
}
}
//다음 필터를 실행하거나, Servlet, Controller를 호출한다.
chain.doFilter(request, response);
} catch (Exception e) {
throw e;
}
}
protected boolean isExclude(String requestURI) {
return PatternMatchUtils.simpleMatch(excludePath, requestURI);
}
}
2.@Configuration 클래스를 작성하여, SessionFilter를 Spring Bean으로 등록한다.
경로(\src\main\java\com\project\config\WebConfig.java)
package com.project.config;
import com.project.web.session.SessionFilter;
import jakarta.servlet.Filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean sessionFilter() {
FilterRegistrationBean<Filter> sessionFilterRegistrationBean = new FilterRegistrationBean<Filter>();
sessionFilterRegistrationBean.setFilter(new SessionFilter()); //SessionFilter 객체를 등록한다.
sessionFilterRegistrationBean.setOrder(0); //Filter의 순서를 정한다. 순서가 작을수록 chain에 먼저 걸림
sessionFilterRegistrationBean.addUrlPatterns("/*"); //해당 필터가 적용될 URL 패턴을 지정한다.
return sessionFilterRegistrationBean;
}
}
3.SignController에서, SessionFilter에 걸러진 사용자가 정상적으로 로그인 했을때 요청한 URI로 다시 redirect한다.
@RequestParam을 사용하여 해당 Parameter를 Mapping한다.
@PostMapping("/signIn")
public String addSignIn(@Validated @ModelAttribute SignInForm signInForm, BindingResult bindingResult, HttpServletRequest request, @RequestParam(defaultValue = "/") String redirectUrl) {
if (bindingResult.hasErrors()) {
return "/login/signIn";
}
User user = signService.findLoginUser(signInForm.getLoginId(), signInForm.getPassword());
if (user == null) {
bindingResult.addError(new ObjectError("signInForm", "아이디나 비밀번호가 틀렸습니다."));
return "/login/signIn";
}else{
//로그인 성공시 세션처리
HttpSession httpSession = request.getSession();
httpSession.setAttribute(SessionConst.SESSION_NAME, user);
}
return "redirect:" + redirectUrl;
}
4.서버 재시작후 테스트
로그인하지 않은 상태에서 localhost:9090/generic으로 접근한다.
5.로그인
다음에는 Spring이 제공하는 Interceptor를 사용해 볼 예정이다.
'프로젝트[종료]' 카테고리의 다른 글
16. ArgumentResolver사용하기, 로그아웃 기능 추가 (0) | 2023.05.11 |
---|---|
15. Spring Interceptor 적용하기 (0) | 2023.05.04 |
13. 로그인 사용자 Session 처리하기 (0) | 2023.04.28 |
12.회원가입 기능 만들기(2) (2) | 2023.04.27 |
11.회원가입 기능 만들기(1) (0) | 2023.04.26 |