μΏ ν‚€ 그리고 μ„Έμ…˜

μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‚¬μš©μžμ˜ μ‚¬μš©μ„±μ„ μ¦μ§„μ‹œν‚€κΈ° μœ„ν•΄μ„œλŠ” μš”μ²­ν•œ μ‚¬μš©μž 정보λ₯Ό μ„œλ²„μ—μ„œ κ΄€λ¦¬ν•˜λŠ” 과정이 ν•„μš”ν•  μˆ˜λ„ μžˆλ‹€. 그런데 HTTP ν”„λ‘œν† μ½œμ€ statelessν•œ μ„±μ§ˆμ„ 가지고 있기 λ•Œλ¬Έμ— μš”μ²­μžμ˜ μƒνƒœλ₯Ό μœ μ§€μ‹œν‚€μ§€ μ•ŠλŠ”λ‹€. κ·Έλ ‡λ‹€λ©΄ μ–΄λ–»κ²Œ μš”μ²­μžμ˜ 정보λ₯Ό μœ μ§€μ‹œν‚¬ 수 μžˆμ„κΉŒ? 

μΏ ν‚€λ§Œ μ‚¬μš©ν•˜μ—¬ μœ μ €μ˜ 정보λ₯Ό μœ μ§€ν•˜λŠ” 방법 

μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈμ˜ λŒ€ν™” 

ν΄λΌμ΄μ–ΈνŠΈ : 둜그인 ν• λž˜ 
μ„œλ²„ : OK, Cookie μ €μž₯μ†Œμ— Member ν‚€κ°’ μ €μž₯ν•΄. λ‹€μŒλΆ€ν„° μš”μ²­ν•  λ•Œ ν¬ν•¨ν•΄μ„œ μ „μ†‘ν•΄μ€˜. 

ν΄λΌμ΄μ–ΈνŠΈ : GET, Cookie 포함, 정보 λ³΄μ—¬μ€˜
μ„œλ²„ : OK, μœ μ € 정보 확인, 정보 λ³΄μ—¬μ€„κ²Œ. 

ν΄λΌμ΄μ–ΈνŠΈ : λΈŒλΌμš°μ € μ’…λ£Œ, 만료 λ‚ μ§œκ°€ μ—†λ„€? μ„Έμ…˜μΏ ν‚€λ‹ˆκΉŒ μ‚­μ œ

                     or 만료 λ‚ μ§œκ°€ μžˆλ„€ μ‚­μ œ μ•ˆν•΄! 만료 λ‚ μ§œμΌ λ•Œ μ‚­μ œ

μΏ ν‚€ κ΅¬ν˜„ν•˜κΈ° Response.setCookie() 

첫 둜그인 성곡

Cookie cookie = new Cookie("memberId", String.valueOf(getId()));
response.setCookie(cookie);
return "redirect:/";


둜그인 둜직

public String login(@CookieValue(name = "memberId"), required = false) Long memberId, Model model) {
    if (memberId == null) {
     // μΏ ν‚€κ°€ μ—†μœΌλ―€λ‘œ 둜그인 창으둜 이동  
    }
    
    // μΏ ν‚€ 확인, μΏ ν‚€ κ°’μœΌλ‘œ μ‚¬μš©μž 정보 κ°€μ Έμ˜€κΈ°
    Member member = memberRepository.findById(memberId);
    model.addAtribute("member", member); 
}


λ‘œκ·Έμ•„μ›ƒ 둜직

cookie.setMaxAge(0);
response.setCookie(cookie);​

 

μΏ ν‚€μ˜ μ‹¬κ°ν•œ λ³΄μ•ˆλ¬Έμ œ 

μΏ ν‚€μ—λŠ” ꡉμž₯히 μ‹¬κ°ν•œ λ³΄μ•ˆλ¬Έμ œκ°€ μ‘΄μž¬ν•œλ‹€. 첫번째둜 μ„œλ²„μ— μ „μ†‘ν•˜λŠ” μΏ ν‚€λ₯Ό μ‘°μž‘ν•˜μ—¬ μ„œλ²„μ— μ˜³μ§€ μ•Šμ€ μš”μ²­μ„ μ‹œλ„ν•  μˆ˜λ„ μžˆλ‹€. λ‘λ²ˆμ§Έλ‘œ μΏ ν‚€κ°€ λΈŒλΌμš°μ €μ— μ €μž₯되기 λ•Œλ¬Έμ— μš”μ²­μž PCκ°€ 털릴 경우 μΏ ν‚€κ°€ ν›”μ³μ§ˆ ν™•λ₯ μ΄ ꡉμž₯히 λ†’μœΌλ©° λΈŒλΌμš°μ €μ—μ„œ μ„œλ²„λ‘œ μΏ ν‚€ 정보λ₯Ό μ „μ†‘ν•˜λŠ” 과정에  ν›”μ³μ§ˆ ν™•λ₯ μ΄ λ†’λ‹€.  λ˜ν•œ 이λ₯Ό 톡해 μΏ ν‚€λ₯Ό νƒˆμ·¨ ν•˜λ©΄  ν•΄μ»€λŠ” μ„œλ²„λ₯Ό 톡해 μ•…μ˜μ μΈ μš”μ²­μ„ 계속 μ‹œλ„ν•˜μ—¬ 연쇄적인 ν”Όν•΄λ₯Ό μž…νžˆκ²Œ λœλ‹€.

μœ„μ˜ λ¬Έμ œλ“€μ„ μ†μ‰½κ²Œ ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 보톡은 쿠킀와 μ„Έμ…˜μ„ 같이 μ‚¬μš©ν•œλ‹€. ν•œλ²ˆ μžμ„Ένžˆ μ•Œμ•„λ³΄λ„λ‘ ν•˜μž. 

 

μ°Έκ³ ) ν† ν°μ΄λž€ λ¬΄μ—‡μΌκΉŒ? μ„Έμ…˜κ³Ό 차이점은 무엇이지?

ν΄λΌμ΄μ–ΈνŠΈ : SessionIDλ‚˜ ν† ν°μ„ ν¬ν•¨ν•˜μ—¬ μš”청을 μ „μ†‘ν•œλ‹€λŠ” μ μ—μ„œλŠ” μœ μ‚¬ν•˜λ‹€.
μ„œλ²„ : μ„Έμ…˜μ„ ν™œμš©ν•˜λŠ” κ²½μš°μ—λŠ” μ„œλ²„κ°€ μ„Έμ…˜ μ €μž₯μ†Œλ₯Ό λ³„λ„λ‘œ μš΄μ˜ν•˜κ³ , ν† ν°μ„ ν™œμš©ν•˜λŠ” κ²½μš°μ—λŠ” μ„œλ²„λŠ” λ‹¨μˆœνžˆ 토큰을 μ•”ν˜Έν™”, λ³΅ν˜Έν™”ν•˜λŠ” μ±…μž„λ§Œμ„ κ°€μ§€κ³  μžˆλ‹€λŠ” κ²ƒμ—μ„œ μ°¨μ΄κ°€ μ‘΄μž¬ν•œλ‹€. 

쿠킀와 μ„Έμ…˜μ„ 톡해 μœ μ €μ˜ 정보λ₯Ό μœ μ§€ν•˜λŠ” 방법 

μΏ ν‚€μ˜ λ³΄μ•ˆλ¬Έμ œλ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” κ²°κ΅­ 맀핑될 μž„μ˜μ˜ 값을 μœ μ €μ—κ²Œ μ „ν•΄μ£Όκ³  μ€‘μš”ν•œ 정보듀은 λͺ¨λ‘ μ„œλ²„μ—μ„œ 관리해야 ν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. μ΄λ ‡κ²Œ μ„œλ²„μ— μ€‘μš”ν•œ 정보λ₯Ό λ³΄κ΄€ν•˜κ³  연결을 μœ μ§€ν•˜λŠ” 것을 μ„Έμ…˜μ΄λΌκ³  ν•œλ‹€.

μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈμ˜ λŒ€ν™” 


ν΄λΌμ΄μ–ΈνŠΈ : λ‘œκ·ΈμΈ ν• λž˜ 
μ„œλ²„ : OK μ •λ³΄κ°€ λ§žλ„€, λ‚΄ μ„Έμ…˜ μ €μž₯μ†Œμ— λ‹ˆ μ •λ³΄λ₯Ό μ €μž₯ ν•΄λ†”μ•Όκ² λ‹€. λ‚˜λŠ” λ„ˆμ—κ²Œ μ •λ³΄λ₯Ό μ°Ύμ„ μˆ˜ μžˆλŠ” Key인 sessionIDλ₯Ό μ€„κ²Œ μΏ ν‚€ μ €μž₯μ†Œμ— μ €μž₯ν•΄.

ν΄λΌμ΄μ–ΈνŠΈ : GET, Cookie ν¬ν•¨, μ •λ³΄ λ³΄μ—¬μ€˜
μ„œλ²„ : OK, sessionId에 λ§€ν•‘λœ μ •λ³΄κ°€ μ‘΄μž¬ν•˜λ„€, μ •λ³΄ λ³΄μ—¬μ€„κ²Œ


μœ„μ™€ κ°™μ΄ μ„Έμ…˜μ„ μ‚¬μš©ν•¨μœΌλ‘œμ„œ ν•΄κ²°λ˜λŠ” λ¬Έμ œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.
1. sessionIDλ₯Ό ν•΄μ»€κ°€ μ˜ˆμƒ λΆˆκ°€λŠ₯ν•œ κ°’μœΌλ‘œ μž„μ˜λ‘œ μƒμ„±ν•œλ‹€. 
2. μ€‘μš”ν•œ μ •λ³΄λ₯Ό μ„œλ²„μ—λ§Œ μ €μž₯ν•˜μ—¬ Local PCμ—μ„œ νƒˆμ·¨λ  μš°λ €κ°€ μ—†λ‹€. 
3. μ„Έμ…˜ λ§Œλ£Œ μ‹œκ°„을 μ§§κ²Œν•˜μ—¬ sessionIDλ₯Ό ν„Έμ–΄κ°€λ„ μ•…μ˜μ μΈ ν–‰λ™μ„ μ·¨ν•  μˆ˜ μ—†λ„둝 ν•œλ‹€.

 

μ„Έμ…˜ κ΅¬ν˜„ν•˜κΈ° 

κΉŠμ€ μ΄ν•΄λ₯Ό μœ„ν•΄  μ§μ ‘ μ„Έμ…˜μ„ κ΅¬ν˜„ν•΄λ³΄μž.  μ’€ λ” μ‰¬μš΄ μ΄ν•΄λ₯Ό μœ„ν•΄ μ„œλ²„와 ν΄λΌμ΄μ–ΈνŠΈμ˜ λŒ€ν™”와 λ‘œμ§μ„ λ§€μΉ­  μ‹œμΌœλ΄€λ‹€. 


ν΄λΌμ΄μ–ΈνŠΈ : λ‘œκ·ΈμΈ ν• λž˜
μ„œλ²„ : λ‚΄ μ„Έμ…˜ μ €μž₯μ†Œμ— λ‹ˆ μ •λ³΄λ₯Ό μ €μž₯ ν•΄λ†”μ•Όκ² λ‹€. λ‚˜λŠ” λ„ˆμ—κ²Œ μ •λ³΄λ₯Ό μ°Ύμ„ μˆ˜ μžˆλŠ” Key인 sessionIdλ₯Ό μ€„κ²Œ μΏ ν‚€ μ €μž₯μ†Œμ— μ €μž₯ν•΄
public void createSession(Object value, HttpServletResponse response) {
    // sessionID 생성
    String sessionId = UUID.randomUUID().toString();

    // μ„Έμ…˜ μ €μž₯μ†Œμ— sessionId와 value μ €μž₯
    sessionStore.put(sessionId, value);

    // sessionId둜 응닡 μΏ ν‚€λ₯Ό μƒμ„±ν•΄μ„œ ν΄λΌμ΄μ–ΈνŠΈμ— 전달
    Cookie cookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
    response.addCookie(cookie);
}



UUID.randomUUID()λ₯Ό ν™œμš©ν•˜κ²Œ 되면 μ‰½κ²Œ UUID  λžœλ€ν‚€λ₯Ό 얻을 수 μžˆλ‹€. μ–»μ–΄λ‚Έ `sessionId`λ₯Ό key둜 ν•˜μ—¬ `Map`에 μœ μ € 정보λ₯Ό μ €μž₯ν•œλ‹€. 과정을 마친 ν›„ `response`에 `sessionId`λ₯Ό ν¬ν•¨μ‹œμΌœ μ‘λ‹΅ν•œλ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ : Get, Cookie ν¬ν•¨, μ •λ³΄ λ³΄μ—¬μ€˜
μ„œλ²„ : OK, sessionId에 λ§€ν•‘λœ 정보가 μ‘΄μž¬ν•˜λ„€, 정보 λ³΄μ—¬μ€„κ²Œ
public Object getSession(HttpServletRequest request) {
    // μ„Έμ…˜κ³Ό κ΄€λ ¨λœ μΏ ν‚€ κ°€μ Έμ˜€κΈ°
    Cookie cookie = findCookie(request, SESSION_COOKIE_NAME);
    if (cookie == null) return null;

    // 쿠킀에 μ €μž₯된 sessionIdλ₯Ό 톡해 μ„Έμ…˜μ„ κ°€μ Έμ˜¨λ‹€
    return sessionStore.get(cookie.getValue());
}

public Cookie findCookie(HttpServletRequest request, String cookieName) {
    Cookie[] cookies =  request.getCookies();
    if (cookies == null) {
        return null;
    }

    return Arrays.stream(cookies)
            .filter(c -> c.getName().equals(cookieName))
            .findAny()
            .orElse(null);
}


μš°μ„  ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ κ°€μ Έμ˜¨ μΏ ν‚€ λͺ©λ‘μœΌλ‘œλΆ€ν„° λ‚΄κ°€ ν•„μš”λ‘œ ν•˜λŠ” μΏ ν‚€λ₯Ό 뽑아내야 ν•œλ‹€. κ·Έλ ‡κ²Œ 뽑아낸 μΏ ν‚€λ‘œλΆ€ν„° `sessionId`λ₯Ό μ–»μ–΄λ‚Έλ‹€. `sessionId`λ₯Ό 톡해 `Map`μ—μ„œ `sessionId`에 ν•΄λ‹Ήλ˜λŠ” μœ μ € 정보λ₯Ό κ°€μ Έμ˜¨λ‹€. 그런데 μœ„μ™€ 같이 μ„Έμ…˜μ„ 직접 일일히 κ΅¬ν˜„ν•˜λŠ” 것은 μƒλ‹Ήνžˆ λΆˆνŽΈν•˜λ‹€. κ°œλ°œμžλ“€μ€ λΆˆνŽΈν•œ 것을 μ ˆλŒ€λ‘œ μ’‹μ•„ν•˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ μ„œλΈ”λ¦Ώλ„ κ°„νŽΈν•˜κ²Œ κ°œλ°œν•  수 μžˆλ„λ‘ μ„Έμ…˜ 자체λ₯Ό μ§€μ›ν•œλ‹€. 

μ„œλΈ”λ¦Ώμ΄ μ œκ³΅ν•˜λŠ” HttpSession 

μ„œλΈ”λ¦Ώμ€ μ„Έμ…˜μ„ μ œκ³΅ν•˜κΈ° μœ„ν•΄ `HttpSession`을 μ œκ³΅ν•œλ‹€.  `HttpSession`은 μ§μ ‘ κ΅¬ν˜„ν•œ μ„Έμ…˜κ³Ό λ™μΌν•œ κΈ°λŠ₯에 **μΆ”κ°€μ μœΌλ‘œ μΌμ •μ‹œκ°„ μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μ‚­μ œλ˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.** μ„œλΈ”릿을 ν†΅ν•΄ `HttpSession`을 μƒμ„±ν•˜λ©΄ `JSESSIONID`λΌλŠ” μ΄λ¦„을 κ°€μ§„ μΏ ν‚€λ₯Ό μƒμ„±ν•œλ‹€. μ„Έμ…˜μ„ μƒμ„±ν•˜λŠ” λ°©λ²•μ„ μ•Œμ•„λ³΄μž.

 

loginController.java

//μ„Έμ…˜μ΄ 있으면 μžˆλŠ” μ„Έμ…˜ λ°˜ν™˜, μ—†μœΌλ©΄ μ‹ κ·œ μ„Έμ…˜μ„ 생성
HttpSession session = request.getSession(/*create μ˜΅μ…˜*/);
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);


μ°Έκ³ ) create μ˜΅μ…˜

1. true (default) : μ„Έμ…˜μ΄ μ—†μœΌλ©΄ μƒˆλ‘œμš΄ μ„Έμ…˜μ„ μƒμ„±ν•΄μ„œ λ°˜ν™˜
2. false : μ„Έμ…˜μ΄ μ—†μœΌλ©΄ μƒˆλ‘œμš΄ μ„Έμ…˜μ„ μƒμ„±ν•˜μ§€ μ•Šκ³  `null`을 λ°˜ν™˜ν•œλ‹€.


μ„Έμ…˜μ„ μƒμ„± ν–ˆμœΌλ‹ˆ μ„Έμ…˜μ„ μ‚¬μš©ν•˜λŠ” λ°©λ²•μ„ μ•Œμ•„λ³΄μž.

homeController.java

HttpSession session = request.getSession(false);
Member loginMember = (Member)session.getAttribute(SessionConst.LOGIN_MEMBER);


μ„œλΈ”λ¦Ώμ—μ„œ μ œκ³΅ν•˜λŠ” HttpSession을 톡해 μ„Έμ…˜μ„ κ΅¬ν˜„ν•˜λŠ” 방법을 μ•Œμ•„λ΄€λ‹€.  μ΄μ •λ„ λ§ŒμœΌλ‘œλ„ μΆ©λΆ„ν•˜μ§€λ§Œ Spring은 μ—¬κΈ°μ„œ 더 λ‚˜μ•„κ°€μ„œ μ’€ 더 νŽΈλ¦¬ν•˜κ²Œ μ„Έμ…˜ κΈ°λŠ₯을 κ΅¬ν˜„ν•  수 μžˆλ„λ‘ @SessionAttributeλ₯Ό μ§€μ›ν•œλ‹€.

homeController.java

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

 

TrackingModes  

λ‘œκ·ΈμΈμ„ 처음 μ‹œλ„ν•˜λ©΄ URL 뒀에 `JSESSIONID`κ°€ ν¬ν•¨λ˜μ–΄ μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€. 

 

http://localhost:8080....../;jsessionid=...

이것은 μ›Ή λΈŒλΌμš°μ €κ°€ μΏ ν‚€λ₯Ό μ§€μ›ν•˜μ§€ μ•Šμ„ λ•Œ, μΏ ν‚€ λŒ€μ‹ μ— URL을 ν†΅ν•΄μ„œ μ„Έμ…˜μ„ μœ μ§€ν•˜λŠ” 방법이닀. 이 방법을 톡해 μΏ ν‚€λ₯Ό μ§€μ›ν•˜κΈ° μœ„ν•΄μ„œλŠ” λͺ¨λ“  URL 뒀에 `JSESSIONID`λ₯Ό ν¬ν•¨ν•˜μ—¬ 전달해야 ν•œλ‹€. λ³΅μž‘ν•œ 방법이라 잘 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€. μ„œλ²„ μž…μž₯μ—μ„œλŠ” λΈŒλΌμš°μ €κ°€ μΏ ν‚€λ₯Ό 지원 ν•˜λŠ”μ§€ μ•ˆν•˜λŠ”μ§€ μ•Œμ§€ λͺ»ν•˜κΈ° 떄문에 μ²˜μŒμ— λ¬΄μž‘μ • URL에 `JSESSIONID`λ₯Ό ν¬ν•¨ν•˜μ—¬ μ „λ‹¬ν•˜λŠ” 것이닀.

λ¬Όλ‘  μœ„μ˜ μ˜΅μ…˜μ„ μ•„λž˜μ™€ κ°™μ€ μ„€μ •μ„ ν†΅ν•΄ μ—†μ•¨ μˆ˜ μžˆλ‹€. 

 

application.proerties

server.servlet.session.tracking-modes=cookie

 

μ„Έμ…˜ νƒ€μž„아웃 μ„€μ • 

보톡 λ‘œκ·Έμ•„μ›ƒμ‹œμ— session.invalidate()κ°€ ν˜ΈμΆœλ˜μ–΄ μ„Έμ…˜μ΄ μ‚­μ œλœλ‹€. 그런데 보톡 μ‚¬μš©μžλ“€μ€ λ‘œκ·Έμ•„μ›ƒ λ²„νŠΌμ„ λˆ„λ₯΄μ§€ μ•Šκ³  λΈŒλΌμš°μ € 자체λ₯Ό μ’…λ£Œν•΄λ²„λ¦°λ‹€. HTTPλŠ” stateless ν”„λ‘œν† μ½œμ΄κΈ° λ•Œλ¬Έμ— μ„œλ²„ μž…μž₯μ—μ„œλŠ” μ‚¬μš©μžκ°€ λΈŒλΌμš°μ €λ₯Ό μ’…λ£Œν•œ 것을 μ•Œμ§€ λͺ»ν•œλ‹€. 

μ΄λ ‡κ²Œ 되면 μ„œλ²„μ—μ„œ μ„Έμ…˜μ„ λ©”λͺ¨λ¦¬μ— μ €μž₯ν•˜μ—¬ κ΄€λ¦¬ν•˜λŠ”λ°, 수천, 수만λͺ…μ˜ μ„Έμ…˜μ΄ 계속 μŒ“μ΄κ²Œ λ˜μ–΄ μ„œλ²„κ°€ ν„°μ Έ λ²„λ¦΄μˆ˜λ„ μžˆλ‹€. λ˜ν•œ λ¬΄ν•œμ • λ‚¨μ•„μžˆλŠ” μΏ ν‚€λ₯Ό ν•΄μ»€μ—κ²Œ νƒˆμ·¨ λ‹Ήν•΄ μ•…μ˜μ μΈ μš”μ²­μ„ λ‹Ήν•  수 μžˆλ‹€. λ”°λΌμ„œ μ„Έμ…˜μ„ μΌμ •μ‹œκ°„μ΄ μ§€λ‚˜λ©΄ μžλ™μœΌλ‘œ μ‚­μ œ λ˜λ„λ‘ μ²˜λ¦¬ν•΄μ•Όλ§Œ ν•œλ‹€.

μ°Έκ³ ) 

μ„Έμ…˜μ€ 정말 μ΅œμ†Œν•œμ˜ λ°μ΄ν„°λ§Œ 보관해야 ν•œλ‹€. μœ μ €μˆ˜κ°€ λ§Žμ•„μ§€κ²Œ 되면 μ„Έμ…˜ λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ μš©λŸ‰μ„ λ²—μ–΄λ‚˜κ²Œ λ˜μ–΄ μ •λ§λ‘œ μ„œλ²„κ°€ ν„°μ§ˆμˆ˜λ„ 있기 λ•Œλ¬Έμ΄λ‹€.

κ·Έλ ‡λ‹€λ©΄ μ„Έμ…˜μ„ μ–Έμ œ μ’…λ£Œμ‹œμΌœμ•Ό ν• κΉŒ? 

λ§Œμ•½ κ°„λ‹¨ν•˜κ²Œ 일정 μ‹œκ°„λ§ˆλ‹€ μ„Έμ…˜μ„ μ‚­μ œμ‹œν‚€λ©΄ 계속 μ‚¬μš©ν•˜λ˜ μ‚¬μš©μžλŠ” κ°‘μžκΈ° λ‘œκ·Έμ•„μ›ƒ λ˜λŠ” λΆˆνŽΈν•œ 상황을 λ§žμ΄ν•˜κ²Œ 될 것이닀. κ·Έλ ‡λ‹€λ©΄ μ–΄λ–€ μ‹œμ μ— μ’…λ£Œν•΄μ•Ό μ‚¬μš©μžκ°€ λΆˆνŽΈν•¨μ„ λŠλΌμ§€ μ•Šκ²Œλ” μ„Έμ…˜μ„ μ’…λ£Œμ‹œν‚¬ 수 μžˆμ„κΉŒ?  httpSession은 default둜 μ‚¬μš©μžκ°€ μ„œλ²„μ— μš”μ²­ν•œ μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ μ‹œκ°„μ„ κ³„μ‚°ν•˜μ—¬ μ’…λ£Œν•œλ‹€.  생λͺ…μ£ΌκΈ° 섀정법을 μ•Œμ•„λ³΄μž, κΈ€λ‘œλ²Œν•œ 섀정법과 μ„Έμ…˜λ§ˆλ‹€ μ„€μ •ν•  수 μžˆλŠ” 섀정법이 μžˆλŠ”λ° μš°μ„  κΈ€λ‘œλ²Œ 섀정법 λΆ€ν„° μ•Œμ•„λ³΄μž. 

application.properties

server.servlet.session.timeout=1800 (1800초)


λ‹€μŒμ€ νŠΉμ • μ„Έμ…˜λ§Œ μ§€μ •ν•˜λŠ” κ²½μš°μ΄λ‹€.

session.setMaxInactiveInterval(1800);


1800초둜 μ§€μ •ν•˜κ²Œ 되면 졜근 μ„Έμ…˜ μ ‘κ·Ό μ‹œκ°„ (`LastAccessedTime`) μ΄ν›„λ‘œ 1800초 μ‹œκ°„μ΄ μ§€λ‚˜λ©΄, WASκ°€ μ„Έμ…˜μ„ μ œκ±°ν•œλ‹€. λ§Œμ•½μ— 1800초 전에 재 μš”μ²­μ„ ν•˜κ²Œ 되면 κ·Έ μ‹œμ λΆ€ν„° λ‹€μ‹œ 1800초λ₯Ό κ³„μ‚°ν•˜κ²Œ λœλ‹€. 


좜처
Inflearn μŠ€ν”„λ§ MVC 2편 - λ°±μ—”λ“œ μ›Ή 개발 ν™œμš© 기술 - κΉ€μ˜ν•œλ‹˜ κ°•μ˜λ₯Ό μˆ˜κ°•ν•˜λ©° μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€