728x90
필터(filter)
필터는 서블릿이 지원하는 수문장이다.
필터 흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
필터 제한
로그인사용자 : HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
비로그인사용자 : HTTP 요청 -> WAS -> 필터 (적절하지 않은 요청이라 판단, 서블릿 호출 X)
필터 체인
필터는 체인으로 구성되는데, 중간에 필터를 자유롭게 추가할 수 있다.
HTTP요청 -> WAS -> 필터1 -> 필터2 -> 필터3 -> 서블릿 -> 컨트롤러
코드로 보는 필터!!!!!!
Q1 . 모든 요청을 로그로 남기는 필터를 개발.
필터 인터페이스를 구현하고 등록하면 서블릿 컨테이너가 필터를 싱글톤 객체로 생성하고 관리한다.
로그필터 LogFilter.java
@Slf4j
public class LogFilter implements Filter {
//init() : 필터 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("log filter init");
}
//doFilter() : 고객의 요청이 올 때 마다 해당 메서드가 호출. 필터의 로직을 구현하는 곳
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
String uuid = UUID.randomUUID().toString();
try {
log.info("REQUEST [{}][{}]", uuid, requestURI);
chain.doFilter(request, response); //다음 필터가 있으면 필터를 호출, 필터가 없으면 서블릿을 호출. 만약 이 로직을 호출하지 않으면 다음단계로 진행이 되지 않음.
} catch (Exception e) {
throw e;
} finally {
log.info("RESPONSE [{}][{}]", uuid, requestURI);
}
}
//destroy() : 필터 종료 메서드. 서블릿컨테이너가 종료될 때 호출
@Override
public void destroy() {
log.info("log filter destroy");
}
}
필터 설정 - WebConfig.java
필터를 등록하는 방법은 여러가지 있지만, 스프링 부트를 사용한다면 filterRegistrationBean를 사용해서 등록하면 됨.
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new LogFilter()); //등록할 필터 지정
filterRegistrationBean.setOrder(1); //필터는 체인으로 동작한다. 순서가 필요함
filterRegistrationBean.addUrlPatterns("/*"); //필터를 적용할 URL 패턴을 지정
return filterRegistrationBean;
}
}
Q2 . 로그인 인증체크 필터 개발
@Slf4j
public class LoginCheckFilter implements Filter {
private static final String[] whitelist = {"/" , "/login" , "/logout" , "/css/*"};
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chian) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request ;
String requestURI = httpRequest.getRequestURI();
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
log.info("로그인 인증체크 필터 시작 {} " , requestURI);
//화이트리스트인 경우에, 인증체크 x
if(isLoginCheckPath(requestURI)) {
log.info("인증체크 로직 실행 {}", requestURI);
HttpSession session = httpRequest.getSession(false);
if(session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청 {}", requestURI);
//로그인으로 redirect
httpResponse.sendRedirect("/login?redirectURL =" + requestURI);
return; //미인증 사용자는 다음으로 진행하지 않고 끝!!
}
}
chain.doFilter(request, response);
} catch (Exception e ) {
throw e;
} finally {
log.info("인증체크 필터 종료{}", requestURI);
}
}
//화이트 리스트인 경우 인증체크 x
private boolean isLoginCheckPath(String requestURI) {
return !PatternMatchUtils.simpleMatch(whitelist, requestURI);
}
}
필터 설정 - WebConfig.java
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new LoginCheckFilter()); //등록할 필터 지정
filterRegistrationBean.setOrder(2); //필터는 체인으로 동작한다. 순서가 필요함
filterRegistrationBean.addUrlPatterns("/*"); //필터를 적용할 URL 패턴을 지정
return filterRegistrationBean;
}
}
RedirectURL 처리 - LoginController
**로그인 이후 redirect 처리
@PostMapping("/login");
public String login (
@Valid @ModelAttribute LoginForm form, BindingResult bindingResult,
@RequestParam(defaultValue = "/") String redirectURL,
HttpServletRequest request) {
if(bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if(loginMember == null) {
bindinResult.reject("loginFail", 아이디 또는 비밀번호가 맞지 않습니다");
return "login/loginForm";
}
// 로그인 성공 처리
HttpSession session = request.getSession();
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
//redirectURL 적용
return "redirect:" + redirectURL;
}
'mini_project > 회원가입, 로그인 구현하기' 카테고리의 다른 글
[spring] 인터셉터(interceptor) (0) | 2021.12.16 |
---|---|
[servlet] 세션(session)생성 "HttpSession" (0) | 2021.12.14 |
[Spring] 세션(session)에 따른 컨트롤 "@SessionAttribute", 타임아웃 설정 (0) | 2021.12.14 |
로그인/로그아웃 구현하기_spring boot, jsp, javascript, mybatis 사용 (0) | 2021.06.09 |
회원가입 구현하기_spring boot, jsp, javascript, mybatis 사용 (2) | 2021.06.09 |