Servlet Http Session

현시기얌·2022년 3월 20일
0

Spring MVC

목록 보기
20/22
post-custom-banner

HttpSession 사용하기

public class SessionConst {
    public static final String LOGIN_MEMBER = "loginMember";
}

// 세션이 있으면 세션 반환, 없으면 신규 세션 생성
final HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, member);

세션 생성과 조회

  • 세션을 생성하려면 request.getSession(true)를 사용하면 된다.
  • request.getSession(true)
    • 세션이 있으면 기존 세션을 반환한다.
    • 세션이 없으면 새로운 세션을 생성해서 반환한다.
  • request.getSession(false)
    • 세션이 있으면 기존 세션을 반환한다.
    • 세션이 없으면 새로운 세션을 생성하지 않는다. null을 반환한다.

세션에 로그인 회원 정보 보관

  • session.setAttribute(SessionConst.LOGIN_MEMBER, member);
    • 세션에 데이터를 보관하는 방법은 request.setAttribute()와 비슷하다.
    • 하나의 세션에 여러 값을 저장할 수 있다.

@SessionAttribute

  • 스프링은 세션을 더 편리하게 사용ㄴ할 수 있도록 @SessionAttribute을 지원한다.
  • 이미 로그인 된 사용자를 찾을 때는 아래와 같이 사용하면 된다. 참고로 이 기능은 세션을 생성하지 않는다.
    @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member member

TrackingModes

  • 로그인을 처음 시도하면 URL이 아래와 같이 jessionid를 포함하고 있는 것을 확인할 수 있다.
    http://localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872
  • 이것은 웹 브라우저가 쿠키를 지원하지 않을 때 쿠키 대신 URL을 통해서 세션을 유지하는 방법이다.
  • 이 방법을 사용하려면 URL에 이 값을 계속 포함해서 전달해야 한다.
  • Thymeleaf 같은 템플릿은 엔진을 통해 링크를 걸면 jsessionid를 URL에 자동으로 포함해준다.
  • 서버 입장에서 웹 브라우저가 쿠키를 지원하는지 하지 않는지 최초에는 판단하지 못하므로 쿠키 값도 전달하고 URL에 jsessionid도 함께 전달한다.
  • URL 전달 방식을 끄고 항상 쿠키를 통해서만 세션을 유지하고 싶으면 아래와 같이 옵션을 넣어주면 URL에 jsessionid가 노출되지 않는다.

    application.properties

    server.servlet.session.tracking-modes=cookie

세션 정보

  • sessionId : 세션Id, JSESSIONID의 값
  • maxInactiveInterval : 세션의 유효 시간
  • creationTime : 세션 생성일시
  • lastAccessedTime : 세션과 연결된 사용자가 최근에 서버에 접근한 시간, 클라이언트에서 서버로 sessionId(JSESSIONID)를 요청한 경우에 갱신된다.
  • isNew : 새로 생성된 세션인지 아니면 이미 과거에 만들어졌고 클라이언트에서 서버로 sessionId(JSESSIONID)를 요청해서 조회된 세션인지 여부

세션 타임 아웃 설정

  • 세션은 사용자가 로그아웃을 직접 호출해서 session.invalidate()가 호출되는 경우에 삭제된다.
  • 그런데 대부분의 사용자는 로그아웃을 선택하지 않고 그냥 웹 브라우저를 종료한다.
  • 문제는 HTTP가 비연결성이므로 서버 입장에서는 해당 사용자가 웹 브라우저를 종료한 것인지 아닌지 인식할 수 없다.
  • 따라서 서버에서 세션 데이터를 언제 삭제해야 하는지 판단하기가 어렵다.

남아있는 세션을 무한정 보관하면 생기는 문제점

  • 세션과 관련된 쿠키(JSESSIONID)를 탈취 당했을 경우 오랜 시간이 지나도 해당 쿠키로 악의적인 요청을 할 수 있다.
  • 세션은 기본적으로 메모리에 생성된다. 메모리의 크키가 무한하지 않기 때문에 꼭 필요한 경우에만 생성해서 사용해야 한다.

세션의 종료 시점

  • 제일 좋은 방법은 사용자가 서버에 최근에 요청한 시간을 기준으로 30분정도 유지해주는 것이다.
  • 이렇게 하면 사용자가 서비스를 사용하고 있으면 세션의 생존시간이 30분으로 계속 늘어난다.
  • 따라서 30분마다 로그인해야 하는 번거로움이 사라진다.
  • HttpSession은 이 방식을 사용한다.

세션 타임 아웃 설정

스프링 부트로 글로벌 설정

application.properties

server.servlet.session.timeout=1800(초)

(글로벌 설정은 분 단위로 설정해야 한다.)

특정 세션 단위로 시간 설정

session.setMaxInactiveInterval(1800);

세션 타임 아웃 발생

  • 세션의 타움아웃 시간은 해당 세션과 관련된 JSESSIONID를 전달하는 HTTP 요청이 있으면 현재 시간으로 다시 초기화 된다.
  • 이렇게 초기화 되면 세션 타임아웃으로 설정한 시간동안 세션을 추가로 사용할 수 있다.
session.getLastAccessedTime() : 최근 세션 접근 시간
  • LastAccessedTime() 이후로 timeout 시간이 지나면 WAS 내부에서 해당 세션을 제거한다.

정리

  • Servlet의 HttpSession이 제공하는 타임아웃 기능 덕분에 세션을 안전하고 편리하게 사용할 수 있다.
  • 실무에서 주의할 점은 세션에는 최소한의 데이터만 보관해야 한다는 점이다.
  • 보관한 데이터 용량 * 사용자 수로 세션의 메모리 사용량이 급격하게 늘어나서 장애로 이어질 수 있다.
  • 추가로 세션의 시간을 너무 길게 가져가면 메모리 사용이 계속 누적될 수 있으므로 적당한 시간을 선택하는 것이 필요하다.
profile
현시깁니다
post-custom-banner

0개의 댓글