스프링 공부 (인프런 김영한 선생님)/스프링 MVC 2편

[스프링 웹 MVC 2편] 009. 로그인 처리 - 서블릿 HTTP 세션

2023. 8. 17. 20:07
목차
  1. HTTPSession - 1
  2. HTTPSession의 사용
  3. 세션 생성과 조회
  4. 세션에 로그인 회원 정보 보관하는 방법
  5. 로그아웃 처리
  6. HTTPSession - 2
  7. 세션 정보와 타임아웃 설정
  8. 세션 타임아웃 설정

HTTPSession - 1

SessionManager와 같은 방식으로 스프링은 HttpSession 기능을 지원한다.

단 이 때 쿠키 이름은 표준 값에 의해 JSESSIONID에 해당하고 값은 추정 불가능한 랜덤 값이다.

HTTPSession의 사용

package hello.login.web;  
// 추상클래스 VS 인터페이스로 사용하라  
public abstract class SessionConst {  
    public static final String LOGIN_MEMBER = "loginMember";  
}

HttpSession에 데이터를 보관하고 조회할 때 같은 이름이 중복되어 사용되므로 상수를 하나 정의함.

@PostMapping("/login")  
public String loginFormV3(@Validated LoginForm loginForm,  
                          BindingResult bindingResult,  
                          HttpServletRequest request){  
    if(bindingResult.hasErrors()){  
        return "login/loginForm";  
    }  

    Member loginMember = loginService.login(loginForm.getLoginId(), loginForm.getPassword());  

    if(loginMember == null){  
        bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");  
        return "login/loginForm";  
    }  

    // 로그인 처리 TODO 쿠키를 만들어서 브라우저로 전송하면 브라우저에서 요청시마다 쿠키를 함께 전달함  

    // 스프링에서 제공하는 HTTP 세션 매니저 사용  
    HttpSession session = request.getSession(); // 세션이 있으면 있는 세션 반환 없으면 새로 만들어서 반환함  
    // 세션에 로그인 회원 정보를 보관한다.  
    session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);  
    // 기본적으로 다 메모리에 저장됨  

    // 세션 생성하려면 .getSession에 파라미터를 true(근데 디폴트라 생략가능)  
    // false라고 하면 새로운 세션을 반환하지 않고 null로 반환한다.  


    //sessionManager.createSession(loginMember, response);  
    return "redirect:/";  

}

세션 생성과 조회

request.getSession(true)의 사용을 통해 기존 세션을 가져오가 없으면 세션을 생성할 수 있다
parameter의 값이 false인 경우 세션이 있으면 기존 세션을 반환하고 없는 경우 null을 반환한다.

request.getSession()은 request.getSession(true)와 동일하다.

세션에 로그인 회원 정보 보관하는 방법

session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember)

세션에 데이터를 보관하는 방법은 @ModelAttribute와 비슷하다.
하나의 세션에는 여러 값을 보관할 수 있다.

로그아웃 처리

@PostMapping("/logout")  
public String logoutV3(HttpServletRequest request){  
    HttpSession session = request.getSession(false);  
    session.invalidate();  
    return "redirect:/";  
}

session.invalidate()를 통해 세션을 제거할 수 있다.

@GetMapping("/")  
public String homeLoginV3(HttpServletRequest request, Model model){  
    // 쿠키 값은 String인데 스프링이 알아서 Converting 해줌  

    HttpSession session = request.getSession(false);  

    if(session == null){  
        return "home";  
    }  

    Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);  

    if(loginMember == null){  
        return "home";  
    }  

    model.addAttribute("member", loginMember);  
    return "loginHome";  
}

request.getSession(false) : true를 사용하면 의미없는 세션이 만들어진다.
session.getAttribute(SessionConst.LOGIN_MEMBER) : 로그인 시점에 세션에 보관한 회원 객체를 찾는다.


HTTPSession - 2

@SessionAttribute

스프링은 세션을 더 편리하게 관리할 수 있도록 위와 같은 애노테이션을 제공한다.

이미 로그인 된 사용자를 찾을 때 사용하면 되나, 직접 세션을 생성하지는 않는다

@GetMapping("/")  
    public String homeLoginV3Spring(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false)  
                                        Member loginMember,  
                                    Model model){  
        // 쿠키 값은 String인데 스프링이 알아서 Converting 해줌  

//        HttpSession session = request.getSession(false);  
//  
//        if(session == null){  
//            return "home";  
//        }  
//  
//        Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);  

        if(loginMember == null){  
            return "home";  
        }  

        model.addAttribute("member", loginMember);  
        return "loginHome";  
    }  
}

세션 정보와 타임아웃 설정

세션이 제공하는 정보는 다음 코드를 통해 얻을 수 있다

package hello.login.web.session;  

import lombok.extern.slf4j.Slf4j;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  

import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  
import java.util.Date;  

@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("getMaxInactiveInterval={}", session.getMaxInactiveInterval());  
        log.info("creationTime={}", new Date(session.getCreationTime()));  
        log.info("lastAccessedTime={}", new Date(session.getLastAccessedTime()));  
        log.info("isNew={}", session.isNew());  

        return "세션 출력";  
    }  
}

sessionId : 세션 ID / JSESSIONID의 값에 해당한다
maxInactiveInterval : 세션의 유효시간 : 단위(초)
creationTime : 세션 생성 일시
lastAccessedTime : 세션과 연결된 사용자가 최근에 서버에 접근한 시간
클라이언트에서 서버로 sessionId(JSESSIONID)를 요청한 경우에 갱신


세션 타임아웃 설정

session.invalidate() 는 /logout 을 통한 컨트롤러 호출시 실행된다.
그런데 유저 대부분은 로그아웃 버튼을 누르지 않는다. 브라우저를 그냥 꺼버리지
그러면 서버 상에서는 이 쿠키에 대한 정보가 남아있게 되는데 비연결성을 가진 HTTP 규약은
서버에서 세션 데이터를 언제 삭제할 것인지 판단하기 어려운 난제를 남긴다.

남아있는 세션을 오래 보관하면 JSESSIONID가 탈취되었을 경우 오랜시간이 지나도 악의적인 요청을 계속할 수 있다. 이 세션들도 메모리에 생성되는데 10만명의 로그인이 실행되면 세션 10만개가 서버에 생성된다.

세션이 메모리를 차지하는 범주가 감당 가능한 수준을 넘어서면 서버가 죽는다.

따라서 세션의 종료 시점을 잘 간을 재서 설정해줘야하는데

열심히 사용하고 있는 사이트가 30분 마다 로그인된다고 생각해보자, 사실 은행 사이트나 보안이 주요한 사이트들은 timeout을 고정으로 잡아서 갱신하지 않는 이상 자동 로그아웃 처리하는데 편의성이 보안성보다 우선시되는 대부분의 사이트들에서는 다른 전략이 필요하다

그래서 세선 생성 시점이 아닌 최근에 요청한 시간을 기준으로 30분 정도를 유지하는 전략을 사용한다.
HttpSession은 이 전략을 사용한다.


스프링 부트 설정을 다음과 같이 진행함으로써 글로벌하게 세션 타임아웃 시간을 설정할 수 있다.
session.setMaxInactiveInterval(1800)

세션에는 최소한의 데이터만 보관하는게 좋다, 안그러면 메모리가 감당이 안될 것이다.

디폴트를 30분이라 생각하자.

'스프링 공부 (인프런 김영한 선생님) > 스프링 MVC 2편' 카테고리의 다른 글

[스프링 웹 MVC 2편] 011. 로그인 처리 - 인터셉터  (0) 2023.08.18
[스프링 웹 MVC 2편] 010. 로그인 처리 - 필터  (0) 2023.08.18
[스프링 웹 MVC 2편] 008. 로그인 처리 - 쿠키. 세션  (0) 2023.08.16
[스프링 웹 MVC 2편] 007. Bean Validation  (0) 2023.08.15
[스프링 웹 MVC 2편] 006. Validation (2)  (0) 2023.08.15
  1. HTTPSession - 1
  2. HTTPSession의 사용
  3. 세션 생성과 조회
  4. 세션에 로그인 회원 정보 보관하는 방법
  5. 로그아웃 처리
  6. HTTPSession - 2
  7. 세션 정보와 타임아웃 설정
  8. 세션 타임아웃 설정
'스프링 공부 (인프런 김영한 선생님)/스프링 MVC 2편' 카테고리의 다른 글
  • [스프링 웹 MVC 2편] 011. 로그인 처리 - 인터셉터
  • [스프링 웹 MVC 2편] 010. 로그인 처리 - 필터
  • [스프링 웹 MVC 2편] 008. 로그인 처리 - 쿠키. 세션
  • [스프링 웹 MVC 2편] 007. Bean Validation
ProgYun.
ProgYun.
인내, 일관성, 그리고 꾸준함을 담습니다.
ProgYun.
Perseverance, Consistency, Continuity
ProgYun.
전체
오늘
어제
  • 분류 전체보기
    • 칼럼
    • 일상생활
      • 월별 회고
      • 인생 이야기 (대학생활)
      • 취준
      • 운동인증
      • 제품 사용 후기와 추천
    • 스프링 공부 (인프런 김영한 선생님)
      • 스프링 핵심원리
      • 스프링 MVC 1편
      • 스프링 MVC 2편
    • 면접 준비
    • 전공
      • OOP 정리
      • Design Pattern
    • 스터디
    • English
      • Electronics(Laptop)
      • 1일 1단어

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 코로나
  • 자존감
  • 대학생
  • 오미크론
  • 윈도우10
  • mason
  • 포맷
  • 편입생
  • 해외직구
  • 일상
  • 피로그래밍
  • 컴공
  • ssd
  • 윈도우재설치
  • p31
  • 자가격리
  • 하이닉스
  • NVME
  • 코로나19
  • 확진자

최근 댓글

최근 글

hELLO · Designed By 정상우.
ProgYun.
[스프링 웹 MVC 2편] 009. 로그인 처리 - 서블릿 HTTP 세션
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.