@SessionAttribute와 세션정보, 세션 타임아웃 설정

2022. 4. 4. 00:21Spring 기초

스프링은 세션을 더 편리하게 사용할 수 있도록 @SessionAttribute를 지원한다.

이미 로그인 된 사용자를 찾을 때는 다음과 같이 사용하면 된다. 추가로, required에 false값을 주면 새로운 세션을 생성하지 않는다.

@GetMapping("/")
public String homeLoginV3Spring( @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false)
Member loginMember, Model model){
  	...
}

위의 @SessionAttribute는 아래 3단계 과정을 생략할 수 있게 해준다.

@SessionAttribute

HttpSession session = request.getSession(); //1. 세션을 받아오는 과정
if (session == null) {
	return "home"; 
}  //2. 세션이 null인지 체크하는 과정

Member member = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER) 
//3. 세션에서 key 값으로 회원 데이터를 조회하는 과정

세션을 뒤져 name = SessionConst.LOGIN_MEMBER와 일치하는 value를 Member loginMember에 담아준다.

 


세션이 제공하는 정보(세션 id, 유효시간, 생성 일시, 사용자 최근 접속시간, isNew 여부 등)

다음과 같은 컨트롤러가 있다.

@Slf4j
@RestController
public class SessionInfoController {
 @GetMapping("/session-info")
 public String sessionInfo(HttpServletRequest request) {
 HttpSession session = request.getSession(false);
     if (session == null) {
    	 return "세션이 없습니다.";
     }
     
     //세션 데이터 출력
     session.getAttributeNames().asIterator()
     .forEachRemaining(name -> log.info("session name={}, value={}", name, session.getAttribute(name)));
    
    log.info("sessionId={}", session.getId());
    log.info("maxInactiveInterval={}", session.getMaxInactiveInterval());
    log.info("creationTime={}", new Date(session.getCreationTime()));
    log.info("lastAccessedTime={}", new Date(session.getLastAccessedTime()));
    log.info("isNew={}", session.isNew());
    
     return "세션 출력";
 }
}

로그 출력 결과는 위의 캡쳐와 같다.

1) session.getId() : 세션 Id, 즉 JSESSIONID의 값이다. 예) 34B14F008AA3527C9F8ED620EFD7A4E
2) session.getMaxInactiveInterval() : 세션의 유효 시간이다.  예) 1800초, (30분) -- 기본값이다.
3) session.getCreationTime():  세션 생성일시 
4) session.getLastAccessedTime(): 세션과 연결된 사용자가 최근에 서버에 접근한 시간, 클라이언트에서 서버로 sessionId ( JSESSIONID )를 요청한 경우에 갱신된다.
5) session.isNew(): 새로 생성된 세션인지, 아니면 이미 과거에 만들어졌고, 클라이언트에서 서버로 sessionId ( JSESSIONID )를 요청해서 조회된 세션인지 여부다.  

로그인 한 상태에서(세션이 생성됨) /session-info로 요청을 보냈기때문에, isNew=false값이 나왔다.
만약 컨트롤러에서

HttpSession session = request.getSession(false); 가 아니라
HttpSession session = request.getSession(true);라면 세션을 새로 생성하기때문에 isNew 값은 true로 나온다.

 

 

세션 타임아웃 설정

 스프링 부트로 글로벌 설정이 가능하다.

application.properties server.servlet.session.timeout=60

세션 유지 시간을 60초로 설정한 모습이다. 기본은 1800(30분)초다. 글로벌 설정을 위와같이 한다면, 세션 타임아웃 설정은 60분이 아니라 60초다. 고로 60초동안 서버에 접근하지 않았다면 새로고침 시 로그아웃된다.

글로벌 설정 외에도, 특정 세션을 단위로 시간 설정이 가능하다.

session.setMaxInactiveInterval(1800);

세션의 타임아웃 시간은 해당 세션과 관련된 JSESSIONID 를 전달하는 HTTP 요청이 있으면 현재 시간으로 다시 초기화 된다. 이렇게 초기화 되면 세션 타임아웃으로 설정한 시간동안 세션을 추가로 사용할 수 있다.

위의 세션정보에서 네번째로 출력한 메서드 결과값인
session.getLastAccessedTime() : 최근 세션 접근 시간
LastAccessedTime 이후로 timeout 시간이 지나면, WAS가 내부에서 해당 세션을 제거한다.