[Java] HttpSession

dondonee·2024년 1월 20일
2
post-thumbnail

HttpSession

웹 용어에서 세션은 단순히 서로 통신하는 두 시스템 사이의 제한된 시간 간격을 의미한다. 여기서 두 시스템은 서버-클라이언트 또는 피어-투-피어 관계일 수 있다.

그러나 HTTP 프로토콜은 상태를 유지하지 않는 무상태 프로토콜이다. 따라서 HTTP 기반의 웹 애플리케이션에서는 로그인 정보처럼 특정 정보를 유지하는 세션 트래킹을 위해 여러 기술을 사용한다.


쿠키 방식

쿠키를 사용하는 것도 하나의 방법이다. 유지해야 할 정보를 쿠키 저장소에 보관해 두었다가 필요할 때 꺼내 사용하는 것이다.

아래는 쿠키를 이용한 간단한 로그인 예시이다.


쿠키를 이용한 로그인 예시

로그인

  1. 클라이언트에서 로그인 정보(ID, password)를 서버에 전송한다.
  2. 서버는 로그인 로직을 처리하고 올바른 로그인이면 쿠키를 생성하고 회원 객체의 ID(memberId)를 담아 클라이언트에 전달한다.
  3. 클라이언트는 쿠키 저장소에 memberId 쿠키를 저장한다.

로그인 상태

  1. 클라이언트는 요청시 memberId라는 쿠키를 전달한다.
  2. 서버는 클라이언트가 전달한 memberId 값으로 member를 조회하여 응답한다.

로그인 - 코드 예시

@PostMapping("/login")
public String login(@Valid @ModelAttribute LoginForm form, BindingResult
bindingResult, HttpServletResponse response) {
 ...
 //로그인 성공 처리
 //쿠키에 시간 정보를 주지 않으면 세션 쿠키(브라우저 종료시 모두 종료)
 Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
 httpServletResponse.addCookie(idCookie);
 return "redirect:/";
}

사용자가 로그인 폼에서 아이디와 패스워드를 입력하고 제출하면 컨트롤러로 서버로 요청이 간다.

위 메서드는 로그인이 성공적인 경우 쿠키에 memberID라는 이름으로 로그인 된 멤버의 객체(loginMember)의 Id를 저장하여 응답에 보낸다.


@GetMapping("/")
public String homeLogin(@CookieValue(name = "memberId", required = false) Long memberId, Model model) {}

리다이렉트 된 홈(/)을 처리하는 homeLogin() 메서드이다. 로그인 상태를 판단하여 로그인 전용 화면 또는 일반 화면을 보여준다.

  • 참고) 스프링 애노테이션 @CookieValue는 쿠키 값을 조회한다. required 속성이 false이기 때문에 memberId라는 이름의 쿠키가 없어도, 즉 로그인하지 않은 상태여도 홈(homeLogin())에 접근할 수 있다.

Member loginMember = memberRepository.findById(memberId);
if (loginMember == null) {
	return "home";
}

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

로그인 상태를 위한 특정 처리를 하고 싶다면 쿠키를 사용하면 된다.

위 코드는 homeLogin() 메서드의 일부로, 쿠키 값 memberId를 사용해서 데이터베이스에서 일치하는 회원이 있는지 조회하는 코드이다.

일치하는 회원이 없다면 비로그인 상태이므로 홈(home)으로 이동시키고, 일치하는 회원이 있다면 정상 로그인이므로 로그인 상태 홈(loginHome)으로 이동시킨다.


쿠키의 단점

그러나 쿠키는 다음과 같은 단점이 있다 :

  • 텍스트 정보만 저장 가능하다.
  • 브라우저 의존적이다. 사용자가 쿠키를 비활성화하면 쿠키를 사용할 수 없다.
  • 각 쿠키 데이터는 4 KB를 초과할 수 없다.
  • 보안에 취약하다. 쿠키 값은 클라이언트에서 쉽게 변경할 수 있다. 또한 쿠키에 저장한 값이 DB에 저장된 본래의 값과 동일하기 때문에 한 번 훔치면 계속해서 사용할 수 있다.


세션 방식

쿠키의 보안 문제를 해결하기 위해서는 중요한 정보는 서버에만 저장하고, 클라이언트와 서버는 추정이 불가능한 임의의 식별자 값으로 연결해야 한다. 이렇게 서버에만 중요 정보를 보관하고 연결을 유지하는 방법을 세션이라 한다.

서블릿은 세션을 위한 HttpSession이라는 훌륭한 객체를 제공하지만 세션의 동작 방식을 이해하기 위해 먼저 단순한 예제를 살펴보자.


세션을 이용한 로그인 예시

로그인

다음은 세션 방식을 이용한 로그인 동작을 표현한 그림이다.

  1. 클라이언트에서 로그인 정보(ID, password)를 서버에 전송한다.
  2. 서버는 로그인 로직을 처리하고 올바른 로그인이면 mySessionId 쿠키를 생성한다.
    • mySessionId 값으로 추정 불가능한 랜덤 값을 할당한다.
    • 자바의 UUID(Universally unique identifier)를 사용하면 확실한 랜덤 값을 얻을 수 있다. (중복 가능성 희박)
  3. 서버의 세션 저장소에 mySessionIdmember를 묶어 보관하고 클라이언트에는 mySessionId만 전달한다.
  4. 클라이언트는 쿠키 저장소에 mySessionId를 저장한다.

로그인 상태

다음은 로그인 이후의 동작이다.

  1. 클라이언트는 요청시 mySessionId라는 쿠키를 전달한다.
  2. 서버는 클라이언트가 전달한 mySessionId의 쿠키 값으로 세션 저장소에서 member를 조회하여 응답한다.

세션 정리

  1. 클라이언트는 회원(member)과 관련된 중요한 정보를 갖고있지 않다.
  2. 클라이언트의 세션 ID(mySessionId)는 추정 불가능한 값이기 때문에 세션 ID를 이용해서 회원과 관련된 값을 가져올 수 없다.
  3. 세션 ID는 일정 시간이 지나면 세션을 종료시키고 새로운 세션 ID를 발급할 수 있기 때문에 보안을 강화할 수 있다. (로그인 후 동작 없이 일정 시간이 지나면 자동 로그아웃 되는 것을 생각해보자)
  4. 세션 방식 또한 쿠키를 통해 클라이언트-서버가 연결된다.


HttpSession

세션은 웹 애플리케이션에서 요구되는 기본적인 기능이다. 서블릿은 세션 트래킹을 위해 HttpSession이라는 인터페이스를 지원한다.

서블릿이 HttpSession 객체를 생성하면 JSESSIONID이라는 쿠키를 생성하고 추정 불가능한 랜덤 값을 할당한다. 애플리케이션은 유저마다 다른 JSESSIONID를 부여하기 때문에 JSESSIONID를 확인하여 어떤 유저의 요청인지 구분할 수 있다.

HttpSession의 값은 서버의 메모리(RAM)에 보관된다.


속성

  • MaxInactiveInterval : 세션의 유효시간 (초 단위)
  • CreationTime : 생성 시간
  • LastAccessedTime : 마지막 접근 시간
  • IsNew : 새로 생긴 세션이면 true, 클라이언트가 서버에서 JSESSIONID를 통해 조회해 온 세션이면 false.

주요 메서드

MethodDescription
public HttpSession getSession()HttpSession 객체를 반환한다. 만약 요청에 관련된 세션이 없는 경우 새 세션을 생성한다.
public HttpSession getSession(boolean create)getSession()에 인자로 false를 전달하는 경우 기존 세션이 없어도 새로 생성하지 않는다. true를 전달하면 새로 생성한다.
public String getId()고유한 세션 ID를 반환한다.
public void invalidate()세션을 무효화한다.

장점

  • 텍스트 뿐 아니라 데이터 셋 등 어느 타입도 저장할 수 있다.
  • 브라우저에 의존하지 않는다.
  • 안전하다.

단점

  • 서버에 저장되는 세션 객체로 인한 성능 오버헤드
  • 데이터 직렬화 및 역직렬화로 인한 오버헤드


참고) 크롬 개발자도구의 Session storage

크롬 개발자도구에서 볼 수 있는 Session storage 섹션은 자바스크립트의 sessionStroage 객체를 위한 것이다(참고). 자바의 HttpSession을 이용한 세션의 값은 서버에서 관리하고 있기 때문에 볼 수 없다.




🔗 References

0개의 댓글