불필요한 세션 생성하지 않기

기존에는 로그아웃시에도 세션이 생성되는 비효율적인 작업이 존재했다.

@PostMapping("/signout")
public ResponseEntity<JsonResponse> signOut(HttpSession session) {

User user = (User) session.getAttribute("user");

log.debug("login user={}", user);

if (user == null) {
        return new ResponseEntity<>(
                ErrorResponse.builder()
                        .message("로그인되지 않았습니다.")
                        .build()
                , HttpStatus.BAD_REQUEST);
}

session.setAttribute("user", null);

return new ResponseEntity<>(JsonResponse.builder()
        .message("로그아웃 되었습니다.")
        .build(), HttpStatus.OK);
}

이렇게 되면, 로그아웃을 시도하면서 빈 세션을 생성하게 된다.

request와 SessionAttribute 사용

로그아웃시에는 request.getSession(false)를 사용하면, 세션이 이미 존재할 때만 세션을 꺼내오고, 새로 세션을 생성하지 않는다. 또, SessionAttribute는 세션을 생성하지 않고, 이미 세션이 존재할 경우에만 name에 해당하는 값을 가져온다.

세션이 존재할 경우에는, invalidate() 메서드로 세션을 아예 비우고, 세션을 비우고, 세션을 무효화해서 해당 세션 객체를 다시 사용하지 못하게 한다. 기존에는 단순히 user의 값을 null로 초기화해주었다.

@PostMapping("/signout")
public ResponseEntity<JsonResponse> signOut(HttpServletRequest request, @SessionAttribute(name = "user", required = false) User user) {
HttpSession session = request.getSession(false);

log.debug("login user={}", user);

if (user == null) {
        return new ResponseEntity<>(
                ErrorResponse.builder()
                        .message("로그인되지 않았습니다.")
                        .build()
                , HttpStatus.BAD_REQUEST);
}

session.invalidate();

return new ResponseEntity<>(JsonResponse.builder()
        .message("로그아웃 되었습니다.")
        .build(), HttpStatus.OK);
}

다른 곳에서 SessionAttribute 사용

다른 곳에서도, 불필요하게 세션을 생성하고 있었다. 예를 들어 도서 반납의 경우에, 로그인하지 않았다면 그냥 권한 없음 페이지로 보내주면 되는데, 이 경우에도 불필요하게 세션을 생성한다.

@PostMapping("/{bookId}/unrent")
public ResponseEntity<JsonResponse> unRent(HttpSession session, @PathVariable("bookId") Long bookId) {
User user = (User) session.getAttribute("user");

if (user == null) {
        return new ResponseEntity<>(ErrorResponse.builder()
                .message("로그인 해주세요.")
                .build(), HttpStatus.FORBIDDEN);
}

...

}

이 경우에도 로그아웃과 비슷하지만, 이 경우 request 객체도 필요하지 않다. SessionAttribute에서 받아온 User객체가 null이라면, 권한 없음 페이지로 보내준다. SessionAttribute는 세션이 이미 존재하는지를 먼저 체크하기 때문에, request.getSession(false)와 내부 동작은 다르지만, 똑같이 불필요한 세션을 생성하지 않는다.

@PostMapping("/{bookId}/unrent")
public ResponseEntity<JsonResponse> unRent(@SessionAttribute(name = "user", required = false) User user, @PathVariable("bookId") Long bookId) {

if (user == null) {
        return new ResponseEntity<>(ErrorResponse.builder()
                .message("로그인 해주세요.")
                .build(), HttpStatus.FORBIDDEN);
}

...

}

댓글

개발자  김철준

백엔드 개발자 김철준의 블로그입니다.

주요 프로젝트