웹 용어에서 세션은 단순히 서로 통신하는 두 시스템 사이의 제한된 시간 간격을 의미한다. 여기서 두 시스템은 서버-클라이언트 또는 피어-투-피어 관계일 수 있다.
그러나 HTTP 프로토콜은 상태를 유지하지 않는 무상태 프로토콜이다. 따라서 HTTP 기반의 웹 애플리케이션에서는 로그인 정보처럼 특정 정보를 유지하는 세션 트래킹을 위해 여러 기술을 사용한다.
쿠키를 사용하는 것도 하나의 방법이다. 유지해야 할 정보를 쿠키 저장소에 보관해 두었다가 필요할 때 꺼내 사용하는 것이다.
아래는 쿠키를 이용한 간단한 로그인 예시이다.
memberId
)를 담아 클라이언트에 전달한다.memberId
쿠키를 저장한다.memberId
라는 쿠키를 전달한다.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
)으로 이동시킨다.
그러나 쿠키는 다음과 같은 단점이 있다 :
쿠키의 보안 문제를 해결하기 위해서는 중요한 정보는 서버에만 저장하고, 클라이언트와 서버는 추정이 불가능한 임의의 식별자 값으로 연결해야 한다. 이렇게 서버에만 중요 정보를 보관하고 연결을 유지하는 방법을 세션이라 한다.
서블릿은 세션을 위한 HttpSession
이라는 훌륭한 객체를 제공하지만 세션의 동작 방식을 이해하기 위해 먼저 단순한 예제를 살펴보자.
다음은 세션 방식을 이용한 로그인 동작을 표현한 그림이다.
mySessionId
쿠키를 생성한다.mySessionId
값으로 추정 불가능한 랜덤 값을 할당한다.mySessionId
와 member
를 묶어 보관하고 클라이언트에는 mySessionId
만 전달한다.mySessionId
를 저장한다.다음은 로그인 이후의 동작이다.
mySessionId
라는 쿠키를 전달한다.mySessionId
의 쿠키 값으로 세션 저장소에서 member
를 조회하여 응답한다.member
)과 관련된 중요한 정보를 갖고있지 않다.mySessionId
)는 추정 불가능한 값이기 때문에 세션 ID를 이용해서 회원과 관련된 값을 가져올 수 없다.세션은 웹 애플리케이션에서 요구되는 기본적인 기능이다. 서블릿은 세션 트래킹을 위해 HttpSession
이라는 인터페이스를 지원한다.
서블릿이 HttpSession
객체를 생성하면 JSESSIONID
이라는 쿠키를 생성하고 추정 불가능한 랜덤 값을 할당한다. 애플리케이션은 유저마다 다른 JSESSIONID
를 부여하기 때문에 JSESSIONID
를 확인하여 어떤 유저의 요청인지 구분할 수 있다.
HttpSession
의 값은 서버의 메모리(RAM)에 보관된다.
MaxInactiveInterval
: 세션의 유효시간 (초 단위)CreationTime
: 생성 시간LastAccessedTime
: 마지막 접근 시간IsNew
: 새로 생긴 세션이면 true
, 클라이언트가 서버에서 JSESSIONID
를 통해 조회해 온 세션이면 false
.Method | Description |
---|---|
public HttpSession getSession() | HttpSession 객체를 반환한다. 만약 요청에 관련된 세션이 없는 경우 새 세션을 생성한다. |
public HttpSession getSession(boolean create) | getSession() 에 인자로 false 를 전달하는 경우 기존 세션이 없어도 새로 생성하지 않는다. true를 전달하면 새로 생성한다. |
public String getId() | 고유한 세션 ID를 반환한다. |
public void invalidate() | 세션을 무효화한다. |
크롬 개발자도구에서 볼 수 있는 Session storage
섹션은 자바스크립트의 sessionStroage
객체를 위한 것이다(참고). 자바의 HttpSession
을 이용한 세션의 값은 서버에서 관리하고 있기 때문에 볼 수 없다.