스프링 MVC2 (2)

Seung·2023년 2월 17일
0
post-thumbnail

쿠키 & 세션

쿠키

  1. 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지
  2. 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
  • 쿠키 사용 (로그인/로그아웃)
로그인시
Cookie cookie = new Cookie("쿠키명","쿠키값");
response.addCookie(cookie);
쿠키를 생성하고 HttpServletResponse에 담아둔다.
로그아웃시
Cookie cookie = new Cookie("쿠키명",null);
cookie.setMaxAge(0);
response.addCookie(cookie);
쿠키 값을 null처리 후 setMaxAge(0)으로 종료날짜를 0으로 지정
  • 쿠키로만 사용시 보안문제가 발생
    • 임의로 클라이언트가 쿠키값 변경 가능
    • 쿠키에 보관된 정보를 훔쳐 갈수 있다.
      -> 세션을 함께 사용하여 보안 문제 해결

세션

  • 서블릿 세션 사용(로그인/로그아웃)
로그인시
HttpSession session = request.getSession();
session.setAttribute("세션명","세션값");
request.getSession(true);
 - 세션이 있으면 기존 세션 반환, 없으면 새로운 세션 생성
 - 기본값
request.getSession(false);
 - 세션이 있으면 기존 세션 반환, 없으면 null 반환
로그아웃시
HttpSession session = request.getSession(false);
if(session != null){
  session.invalidate();
}
session.invalidate(); 세션을 제거한다.
  • @SessionAttribute 사용
public String Login(
@SessionAttribute(name="loginMember", required=false) Member loginMember, 
Model model){
	 if (loginMember == null){
     	return "home";
     }
     
     model.addAttribute("member",loginMember);
     return "loginHome";
}
@SessionAttribute 사용시 @ModelAttribute또는 model.addAttribute()를 사용해서 
객체를 저장할 경우 세션에 저장이 되도록 지정할 수 있습니다.
  • 세션 타임아웃 설정
스프링 부트로 글로벌  설정
application.properties
server.servlet.session.timeout=1800 
기본값 1800 (30분)

특정 세션단위 시간설정
session.setMaxInactiveInterval(1800);

필터 & 인터셉터

필터

필터 흐름
HTTP요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
필터제한
HTTP요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러 (로그인 사용자)
HTTP요청 -> WAS -> 필터(적절하지 않은 요청시, 서블릿 호출 X) (비로그인 사용자)
필터 체인
HTTP요청 -> WAS -> 필터1 -> 필터2 -> ~~ -> 서블릿 -> 컨트롤러

  • 필터 인터페이스
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(){}
}
  • 필터 인터페이스 사용
private static final String[] whitelist = {"/","/login","/css/*"};

public class LoginCheckFilter implements Filter {
	
    public void doFilter(ServletRequest request,
    ServletResponse response, FilterChain chain) 
    throws IOException, ServletException{
    	
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();
        
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        try{
        	//whitelist와 URI를 비교하여 필터해야하는 URI구분
            if(!PatterMatchUtils.simpleMatch(whitelist,requestURI){
            HttpSession session = httpRequest.getSession(false);
            	if(session == null || session.getAttribute("loginMember") == null){
            		//미인증 사용자
                    httpResponse.sendRedirect("/login?redirectURL="+requestURI);
                    return; //미사용자는 다음 필터 체인으로 진행하지 않고 종료
            	}
            }
            
            chain.doFilter(request,response);
            //다음필터체인으로 진행 없을 경우 서블릿으로
        } catch (Exception e) {
        	throw e; //톰캣까지 예외 보내기
        } finally {
        
        }    
    }
}
  • WebConfig 필터설정
@Configuration
public class WebConfig {

	@Bean
    public FilterRegistrationBean loginCheckFilter(){
    FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
    
    filterRegistrationBean.setFilter(new LoginCheckFilter()); //등록할 필터 지정
    filterRegistrationBean.setOrder(1); //필터 체인동작 숫자 낮을 수록 먼저 동작
    filterRegistrationBean.addUrlPattern("/*"); //URL패턴 지정 해당부분을 모든 요청을 받으니 화이트리스트 사용한거임.
    return filterRegistrationBean;
    
    }
}

스프링 인터셉터

인터셉터 흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
스프링 인터셉터 제한
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 (적절하지 않은 요청시 컨트롤러 호출X)
스프링 인터셉터 체인
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터1 -> 스프링 인터셉터2 -> ~~ ->컨트롤러

  • 스프링 인터셉터 인터페이스
public interface HandleInterceptor {
	//컨트롤러 호출전 응답이 true시에 다음으로 진행,false시 진행X
	default boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, Object hablder) throws Exception {}
    //컨트롤러 호출 후
    default void postHandle(HttpServletRequest request,
    HttpServletResponse response, Object hanlder, 
    @Nullable ModelAndView modelAndView) throws Exception {}
    //요청완료 이후, view렌더링 된 이후에 호출
    default void afterCompletion(HttpServletRequest request,
    HttpServletResponse response, Object handler,
    @Nullable Exception ex) throws Exception{}
}
  • 스프링 인터셉터 예외상황
    ( 참고 김영한의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술)

  • 스프링 인터셉터 사용

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?redirectURL="+ reuqestURI);
            return false;
        }
        return true;
        
    }
}
  • Webconfig 인터셉터 등록
@Configuration
public class Webconfig implements WebMvcConfigurer {
	@Override
    public void addInterceptor(InterceptorRegistry registry) {
    	registry.addInterceptor(new LoginCheckInterceptor())
        		.order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/","/login","/css/**");
    }
}
profile
한번 해봅시다.

0개의 댓글