본문 바로가기

스프링/Spring MVC

세션 정보와 타임아웃 설정

세션 정보 확인

@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("lastAccessTjme={}",new Date(session.getLastAccessedTime()));
        log.info("isNew={}", session.isNew());
        return "세션 출력";
    }
}
  • sessionId : 세션 Id, JSESSIONID의 값이다. 예) 02ABB22139E94635A136296368F6F995
  • maxInactiveInterval : 세션의 유효 시간, 예) 기본값 1800초, (30분)
  • creationTime : 세션 생성 일시 예) Tue Oct 26 17:26:56 KST 2021
  • lastAccessedTime : 세션과 연결된 사용자가 최근에 서버에 접근한 시간, 클라이언트에서 서버로 sessionId (JSESSIONID)를 요청한 경우에 갱신된다. 예) Tue Oct 26 17:26:57 KST 2021
  • isNew : 새로 생성된 세션인지, 아니면 이미 과거에 만들어졌고, 클라이언트에서 서버로 sessionId ( JSESSIONID )를 요청해서 조회된 세션인지 여부 예) 새로 생성된 세션인 경우 true, 과거에 세션을 만든 경우 false

 

세션 타임아웃 설정

세션은 사용자가 로그아웃을 직접 호출해서 session.invalidate()가 호출되는 경우에 삭제됩니다. 

그런데 대부분의 사용자는 로그아웃을 선택하지 않고, 그냥 웹 브라우저를 종료합니다. 문제는 HTTP가 비연결성(ConnectionLess)이므로 서버 입장에서는 해당 사용자가 웹 브라우저를 종료한 것인지 아닌지를 인식할 수 없습니다. 따라서 서버에서 세션 데이터를 언제 삭제해야 하는지 판단하기가 어렵습니다.

이 경우 남아있는 세션을 무한정 보관하면 다음과 같은 문제가 발생할 수 있습니다.

  • 세션과 관련된 쿠키(JSESSIONID)를 탈취당했을 경우 오랜 시간이 지나도 해당 쿠키로 악의적인 요청을 할 수 있습니다.
  • 세션은 기본적으로 메모리에 생성됩니다. 메모리의 크기가 무한하지 않기 때문에 꼭 필요한 경우만 생성해서 사용해야 합니다. 10만 명의 사용자가 로그인하면 10만 개의 세션이 생성되는 것입니다.

 

세션 타임아웃 설정

스프링 부트로 글로벌 설정

application.properties

server.servlet.session.timeout=60 : 60초, 기본은 1800(30분)

글로벌 설정은 분 단위로 설정해야 합니다. 60(1분), 120(2분)

그래서 해당 타임아웃의 최소 값은 60입니다.

 

특정 세션 단위로 시간 설정

session.setMaxInactiveInterval(1800); //1800초

 

 

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

session.getLastAccessedTime() : 최근 세션 접근 시간

 

LastAccessedTime 이후로 timeout 시간이 지나면, WAS가 내부에서 해당 세션을 제거합니다.