SPRING/Spring MVC

[SpringMVC] 서블릿 세션(Servlet Session) 이용하기

IT록흐 2023. 8. 30. 23:59
반응형

 

 

[SpringMVC] Session( 세션 )이란?

[SpringMVC] Cookie ( 쿠키 ) 클라이언트가 웹페이지에 접근하려고 한다. 웹페이지는 회원만 접근 가능하므로 서버는 클라이언트 요청에 로그인 페이지로 응답한다. 클라이언트는 ID와 비밀번호를 입

lordofkangs.tistory.com

 

지난 포스팅에서 세션에 대해서 알아보았다. 

 

JAVA는 서블릿 패키지에서 세션을 사용할 수 있도록 제공하고 있다. 

 

 

LoginController

@PostMapping("/login")
public String login(@Valid @ModelAttribute LoginForm form, HttpServletRequest request){

    // DB에서 회원정보 조회 [ 비즈니스 로직 ]
    Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

    // 회원정보가 없는 경우
    if(loginMember == null){
        bindingResult.reject("loginFail","아이디 또는 비밀번호가 맞지 않습니다. ");
        return "login/loginForm";
    }

    // 회원정보가 있는 경우

    // 세션 생성
    HttpSession session = request.getSession(true);
    // 생성된 세션에 세션명과 회원정보 저장
    session.setAttribute(SessionConst.LOGIN_MEMBER,loginMember);
    
    // 홈페이지 경로로 리다이렉트
    return "redirect:/";

}

 

로그인 url로 요청이 들어오면 LoginController의 login 메소드가 호출된다. ID/Password로 회원정보를 조회하고 회원정보가 있다면 HttpServletRequest 객체의 getSession 메소드를 호출한다. 이때 파라미터로 true를 넘긴다. Request 객체 안에는 클라이언트가 보낸 쿠키가 저장되어 있다. 쿠키 안에는 세션ID가 들어있는데 세션ID와 매핑되는 회원정보가 없는 경우, 파리미터를 true를 넘기면 세션을 새로 생성한다. 새로 생성된 세션은 HttpSession 객체로 반환되고 setAttribute 메소드로 속성명과 회원정보를 입력한다. 속성명과 회원정보를 매핑하여 저장한다는 의미는 단일 세션 하나에 다양한 정보가 저장될 수 있음을 의미한다. 회원정보를 가져올 수 있는 key값을 속성명으로 하여 저장한다. 

 

랜덤하게 생성된 세션ID는 쿠키에 저장되어 클라이언트에 전달된다. 클라이언트는 리다이렉트된 홈페이지 경로로 받은 쿠키를 전송한다. 

 

HomeController

@GetMapping("/")
public String homeLogin(HttpServletRequest request, Model model){

    // 세션 조회
    HttpSession session = request.getSession(false); 
    
    // 세션이 없다면 일반 홈페이지 경로로 이동
    if(session == null){
        return "home";
    }
    
    // 세션이 있다면 세션 객체에서 회원정보 조회
    Member loginMember = (Member)session.getAttribute(SessionConst.LOGIN_MEMBER);

    // 회원정보가 없다면 일반 홈페이지 경로로 이동
    if(loginMember == null){
        return "home";
    }
    
    // 회원정보가 있으면 로그인된 홈페이지 경로로 이동
    model.addAttribute("member",loginMember);
    return "loginHome";

}

 

 

Request 객체 안에는 클라이언트가 보낸 쿠키가 들어있다. 쿠키 안에 저장된 세션ID로 세션저장소에서 세션을 조회한다.

 

HttpServletRequest 객체의 getSession 메소드를 호출하는데, 이때는 파라미터로 false를 넘긴다. 세션 조회가 목적이지 생성이 목적이 아니므로 true가 아닌 false를 넘긴다. 조회에 성공하면 조회된 세션정보가 담긴 세션객체를 반환한다. 세션객체에는 세션ID, 생성시간, 마지막접근시간, 회원정보 등 다양한 데이터가 담겨있다.  회원정보를 가리키는 key를 파라미터로 전달하여 회원정보를 가져온다. 회원정보가 존재한다면 회원정보를 뷰템플릿으로 전달하여 로그인된 홈페이지 화면을 클라이언트에 전달한다. 

 

과정을 간략히 정리하면 아래와 같다.

 

1) Request에 저장된 쿠키에서 세션ID를 가져온다.

2) 세션ID와 매핑되는 세션객체를 가져온다. 

3) 세션객체에서 회원정보를 추출한다. 

4) 회원정보를 뷰템플릿으로 넘긴다.

 

여기서 Spring은 1), 2), 3)을 자동화하는 어노테이션을 제공한다. 

 

HomeController( @SessionAttribute 사용 )

@GetMapping("/")
public String homeLoginV3Spring(@SessionAttribute(name=SessionConst.LOGIN_MEMBER,required = false) Member loginMember, Model model){

    if(loginMember == null){
        return "home";
    }

    model.addAttribute("member",loginMember);
    return "loginHome";
}

 

@SessionAttribute에 세션명을 설정하면, Spring이 알아서 HttpServletRequest 객체에서 세션객체를 조회하고 세션명으로 회원정보를 가져와 파라미터로 넘겨준다. 주의할 점은 세션객체 조회시 파라미터로 false를 전달하므로, @SessionAttribute는 세션조회시에만 사용해야 한다. 세션 생성과정에서는 사용하면 안 된다. 

 

이렇듯, 세션이 정상적으로 조회되어 회원정보를 가져올 수 있게 되면, 클라이언트는 ID/Password 없이도 쿠키만으로 웹서비스에 접근할 수 있게 된다. 

 

 

로그인 화면

 

클라이언트가 전달 받은 쿠키정보

 

로그인된 홈페이지 화면

 

 

 

 

추가로 서블릿 세션에 적용가능한 몇가지 설정을 알아보자. 

 

1) 쿠키를 지원하지 않는 브라우저를 위한 작업 종료하기

 

application.properties

server.servlet.session.tracking-modes=cookie

 

몇몇의 웹브라우저는 쿠키를 지원하지 않는다. 쿠키를 지원하는 웹브라우저든, 쿠키를 지원하지 않는 웹브라우저든, 첫 로그인 요청을 할때는 쿠키를 보내지 않는다. 그러므로 서버입장에서는 브라우저가 쿠키를 지원하는지, 지원하지 않는지 구분할 수가 없다. 그래서 서버는 브라우저에게 쿠키를 반환함과 동시에 리다이렉트 URL을 아래와 같이 보낸다. 

 

http://localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872

 

쿠키를 지원하지 않는 브라우저는 위 경로로 세션을 유지할 수 있다. 반면 쿠키를 가지고 있는 브라우저는 위 경로가 쓸데없이 길다랗다. 그래서 두번째 요청부터는 서버가 쿠키를 가지고 있는 브라우저에게는 세션ID가 제거된 URL을 반환하고 쿠키없이 계속 세션ID가 붙은채 요청하는 URL에게는 세션ID도 같이 URL로 전달한다.

 

이는 소수의 브라우저를 위한 배려와 같다. 그러므로 이와같은 작업을 끄고 싶다면 위 설정을 application.properties에 추가하면 된다.

 

 

2) 세션 타임아웃 설정하기

 

application.properties

server.servlet.session.timeout=1800

 

글로벌하게 모든 세션의 타임아웃을 한번에 설정하고 싶다면 위 설정을 추가하면 된다. 세션 만료시간은 세션에 마지막 접근을 한 시간을 기준으로 측정된다. 1800초는 30분이다. 서버에 마지막 접근을 한 뒤 30분이 지나면 세션은 자동으로 세션저장소에서 제거된다. 

 

session.setMaxInactiveInterval(1800);

 

만약 특정 세션만 타임아웃을 설정하고 싶다면 아래와 같이 세션 객체의 setter 함수를 호출하면 된다. 적절한 시간이 설정되어야 메모리 관리를 효율적으로 할 수 있다.

 

 

 


 

 

참고자료

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com

 

반응형