@PostMapping("/login")
String login(HttpServletResponse response) {
Cookie cookie = new Cookie("name", "value");
response.addCookie(cookie);
}
세션 쿠키
@PostMapping("/login")
String login(HttpServeltRequest request) {
Cookie[] cookies = request.getCookies();
}
Spring은 편하게 Cookie를 다룰 수 있도록 @CookieValue
annotation을 제공한다.
@PostMapping("/login")
String login(@CookieValue(name = "name", required = false) Long id) {
if (id == null) {...}
}
name
value
name
속성과 같은 역할 수행 (name의
alias)required
String login(@CookieValue(name="name" required = true) Long id) {...}
400 Bad Request
를 응답함String login(@CookieValue(name="name" required = false) long id) {...}
null
값이 들어감java.lang.IllegalStateException
이 발생 & 500 Internal Server Error
를 응답함 -> 특별한 이유가 없으면 Reference Type을 사용하자defaultValue
defaultValue
를 사용 = 암시적으로 required = false
삭제 = 만료 = max-age
를 0으로 만들기
public String logout(HttpServletResponse response) {
// 만료시킬 쿠키와 동일한 이름의 쿠키를 새로 생성
Cookie cookie = new Cookie("name", "value");
cookie.setMaxAge(0); // max-age를 0으로 설정
response.addCookie(cookie);
}
Spring에서 Session은 쿠키에 JSESSIONID:추정_불가능한_값
형태로 저장된다.
무의식적으로 사용하는 Spring의 HttpSession
은 톰캣의 HttpSession
이고, 톰캣에 내부적으로 저장, 관리된다.
스프링은 Servlet을 통해 Session 기능을 제공한다.
javax.servlet.http.HttpSession
// 요청과 관련된 세션 객체가 있으면 그대로 반환, 없으면 새로 생성
HttpSession session = request.getSession();
// '없으면 새로 생성'이 기본값으로 사용된다.
HttpSession session = request.getSession(true);
// 기존 값이 없어도 새로 생성 X (null 반환)
HttpSession session = request.getSession(false);
// 세션에 속성값을 할당, 여러 개 가능
session.setAttribute("name", "value");
// 속성 이름으로 데이터 찾아오기
Object name = session.getAttribute("name");
// Cookie에 저장된 세션 아이디 불러오기
String id = session.getId();
// 세션에 저장된 속성 이름 목록
Enumeration<String> attributeNames = session.getAttributeNames();
// 세션 유효 시간 (초)
int maxInactiveInterval = session.getMaxInactiveInterval();
// 생성된 시간 (unix time 기준 몇 초 후에 생성됐는가)
long creationTime = session.getCreationTime();
// new Date(session.getCreationTime())로 날짜 확인 가능
// 마지막으로 접근한 시간 (unix time 기준 몇 초가 흘렀는가)
long lastAccessedTime = session.getLastAccessedTime();
// new Date(session.getLastAccessedTime()) 로 날짜 확인 가능
// 새로 생성된 세션인가
boolean isNew = session.isNew();
Spring은 편하게 Session을 다룰 수 있도록 @SessionAttribute
annotation을 제공한다.
public String login(@SessionAttribute(name = "name") Member member) {
...
}
세션 객체에 name
이라는 이름으로 저장된 데이터를 불러온다.
이 기능은 새로 세션을 생성하지 않는다, 단순히 세션을 조회할 뿐
name
의 alias 역할Spring은 브라우저에게 쿠키를 통해 Session ID를 전달한다. 그런데 만약 브라우저가 Cookie 기능을 제공하지 않을 수도 있다.
이를 해결하기 위해, Spring은 쿠키로 세션 아이디를 전달할 뿐만 아니라, 다음처럼 Url에 세션 아이디를 붙여 전달한다. (Tracking Mode)
localhost:8080/;JSESSIONID=123456788
그런데 이 방식을 사용하면 사용자 인증이 필요한 모든 요청 URL에 세션 아이디를 붙여야 한다. 이를 ThymeLeaf같은 템플릿 앤진이 도와주기도 한다.
설정을 통해 TrackingMode를 사용하지 않을 수 있다.
// application.properties
server.servlet.session.tracking-mode=cookie
일반적으로 사용자는 로그아웃
버튼을 눌러 명시적으로(?) 로그아웃을 수행하지 않는다. 대충 브라우저를 닫을 뿐
Http Protocol은 Connectionless
이기 때문에, 사용자가 브라우저를 종료했는지 인식할 수 없다.
따라서 메모리 측면에서 서버의 Session을 효과적으로 정리해야 할 필요성이 있다.
이를 Session에 만료 시간을 설정함으로써 해결할 수 있다.
단순히 30분 뒤에 종료되도록 설정하면 안되므로(아직 사용중일 수도 있다),
사용자의 마지막 요청으로부터 30분 후에 세션을 제거한다.
마지막 접근 시간 후, 만료시간이 도달했을 때 세션을 제거하는 작업은 WAS(Tomcat)이 수행한다.
// application.properties
// 세션의 생명 주기를 60초로 설정, 기본 값은 1800(30분)
server.servlet.session.timeout=60
// 60으로 나눠지는 단위의 시간으로 설정해야 한다.
session.setMaxInactiveInterval(1800);