[Spring] Cookie와 Session

벼랑 끝 코딩·2025년 3월 31일

Spring

목록 보기
9/16
post-thumbnail

HTTP는 무상태 프로토콜(Stateless) 이라는 특징을 가지고 있어,
사용자의 필요한 최소한 정보를 저장하기 위해 쿠키라는 기능을 사용한다.

쿠키는 만료 날짜가 정해진 영속 쿠키
만료 날짜 지정을 생략할 경우 브라우저 종료시 까지 유지되는 세션 쿠키가 있다.
실제 쿠키를 어떻게 사용하면 좋을지 알아보자.

쿠키

Cookie cookie = new Cookie("key", value)
HttpServletResponse.addCookie(cookie)

// ** 응답 메시지 헤더에 쿠키 추가 **
Set-Cookie: key=value

쿠키는 객체를 통해 생성할 수 있다.
addCookie() 메서드를 호출하여 Response의 Header에 쿠키를 추가할 수 있다.

무상태 프로토콜로 설계된 HTTP에서 Client는 서버로부터 쿠키를 전달받으면
로그인과 같은 정보 쿠키에 담아 보내서 통신을 지속할 수 있다.
서버는 파라미터를 통해 Client가 전달한 쿠키를 확인할 수 있다.

public String method(@CookieValue(name = "key", required = false) Object value) 

name element를 통해서 Cookie의 값을 받아볼 수 있다.
쿠키 없이 request가 발생할 수 있으므로 required = false로 설정한다.

value가 조건을 만족하지 못하는 경우 접근을 제어하는 등 쿠키를 활용할 수 있다.

Cookie cookie = new Cookie("key", value);
cookie.setMaxAge(0);
HttpServletResponse.addCookie(cookie);

로그아웃과 같은 상황을 처리하려면 쿠키를 만료해야 한다.
setMaxAge() 메서드를 호출하여 cookie의 지속 시간을 0으로 설정하고
시간이 만료된 쿠키를 응답에 전달한다.

쿠키는 임의로 변경할 수 있다.
이 말은 해킹이 가능하여 보안에 취약하다는 의미이다.

따라서 쿠키에는 개인 정보와 같은 민감한 내용을 포함해서는 안된다.
쿠키는 임의의 값을 설정하여 저장하고,
서버 측에서 쿠키 값과 정보를 매핑하여 인식해야 한다.

추가적으로 만료 시간을 짧게하여 보안을 더욱 강화해야 한다.

Session

사용자가 로그인 또는 개인 정보와 같은 중요한 정보를 서버에 전달하면
서버는 임의의 값을 생성하여 Session ID를 생성하고
Map 형식으로 정보와 Session ID를 저장소에 보관한다.
쿠키에는 임의의 값인 Session ID를 전달하고
서버 내부에서 Session ID를 통해 매핑하여 정보를 조회하는 방식을 사용한다.

HttpSession

이러한 과정을 통틀어 Session이라고 부르며,
Spring은 위 과정을 효율적으로 수행하기 위해 HttpSession 객체를 지원한다.

getSession()

HttpSession session = HttpServletRequest.getSession();

Client Request를 전달받으면, 서버는 우선 session을 획득한다.
getSession() 메서드를 호출하여 세션을 생성할 수 있는데
세션이 있으면 반환하고 없으면 생성한다.
getSession() 메서드의 기본 값은 true이고(getSession(true)),
getSession(false) 메서드 호출 시 세션이 없어도 새로 생성하지 않는다.

세션을 생성 방법은 JSESSIONID라는 임의의 값을 생성하는 것이다.
서버에서 JSESSIONID를 생성하면 쿠키로 Client에게 전달한다.
Client는 전달 받은 JSESSIONID를 요청 시마다 쿠키에 담아 서버로 전달한다.
서버에서는 getSession() 메서드를 통해 해당 JSESSIONID를 확인할 수 있는 것이다.

setAttribute(key, value)

HttpSession session = HttpServletRequest.getSession();
session.setAttribute("key", value);

서버는 Client가 전달한 데이터를 Session에 저장할 수 있다.
값을 저장할 때는 세션의 setAttribute(key, value) 메서드를 호출한다.

session.getAttribute("key");

getSession()을 통해 세션이 있는지 확인했다면,
세션의 getAttribute(key) 메서드를 호출하여
이전에 저장했던 값 중 필요한 정보를 조회할 수 있다.

invalidate()

session.invalidate()

로그아웃과 같은 Client 요청이 들어오면 Session을 제거해야 한다.
invalidate() 메서드를 호출하면 편리하게 세션을 제거할 수 있다.

@SessionAttribute

public String method(@SessionAttribute(name = key, required = false) Object value)

HttpSession은 직접 객체를 생성해야 하는 번거로움이 있다.
파라미터에 @SessionAttribute 애노테이션을 선언하면
세션에 저장한 정보를 편리하게 조회할 수 있다.

@SessionAttribute는 세션을 생성하지 않는다.
따라서 HttpSession 객체를 생성하지 않아도 되고
세션의 정보를 따로 저장하지 않고 편리하게 조회하며,
자동으로 형변환하여 객체로 받아볼 수 있다.

세션 데이터를 직접 추가해야 하는 경우 HttpSession 기능을 사용하고,
이미 생성된 세션 데이터를 간편하게 조회하는 경우 애노테이션을 사용하자.

Session Timeout

쿠키는 보안 강화를 위해 만료 시간을 짧게 설정해야 했다. 세션도 마찬가지다.
또한 세션은 생성하는 만큼 메모리가 낭비된다.
서버 입장에서는 사용자가 대부분 로그아웃 없이 웹을 종료하는 것처럼,
사용자의 세션 종료 시점을 파악학시 어렵기 때문에 메모리 낭비를 막기 위해서라도
시간이 지나면 세션을 만료해야 한다.

[application.properties]

server.servlet.session.timeout=n

Session은 application.properties
다음과 같이 설정하여 만료 시간을 설정할 수 있다.
단위는 이고 기본 1800초로 설정된다.

JSESSIONID를 전달하는 Request가 발생하면 시간은 초기화된다.

TrackingModes

서버 입장에서는 쿠키를 전달한다고 하더라도,
웹 브라우저가 쿠키 기능을 지원하지 않는지 알 수 없다.
따라서 JSESSIONID를 생성하여 쿠키로도 전달하지만
Url에도 JSESSIONID를 포함하여 전달한다.

application.properties

[application.properties]

server.servlet.session.tracking-modes=cookie

Url 전달 방식을 원하지 않는다면
application.properties에 다음과 같이 설정하면 쿠키 방식만 지원한다.

마무리

무상태 프로토콜의 특징을 가진 HTTP에서 쿠키, 세션의 사용은 매우 중요하다.
쿠키의 개념을 이해하고 Session의 동작 과정과 사용법을 자세히 익히도록 하자.

profile
복습에 대한 비판과 지적을 부탁드립니다

0개의 댓글