출처 | https://sh77113.tistory.com/243
https://hyewoncc.github.io/session-cookie-jwt/
HttpSession으로 간단한 상태 유지를 한 사례를 깃헙에서 볼 수 있다. 해당 브랜치의 애플리케이션을 실행하면 간단한 페이지가 뜬다. 삐약삐약을 누르면 병아리가 추가된다
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.*;
import jakarta.servlet.http.HttpSession;
public class SessionController {
private static final String SESSION_KEY = "jihwan";
@GetMapping
public ModelAndView main(HttpSession session) {
Object attribute = session.getAttribute(SESSION_KEY);
// 세션 값을 읽어온다.
ModelAndView modelAndView = new ModelAndView("session.html");
Map<String, Object> pmap = new HashMap<>();
// 여기에 {Session Key : attribute} 이렇게 저장한다.
if (attribute != null) {
/* 여기가 keyPoint */
pmap.put(SESSION_KEY, attribute);
session.setAttribute(SESSION_KEY, (int) attribute);
// pmap에도 저장하고 session에도 저장한다.
return modelAndView.addAllObjects(pmap);
// addAllObject(Map values) : view에 전달할 값을 Map에 name-value로 저장하여 한번에 설정
}
// 세션키가 존재하지 않는 경우에
pmap.put(SESSION_KEY, 0);
session.setAttribute(SESSION_KEY, 0);
return modelAndView.addAllObjects(pmap);
// 기본값으로 0을 설정하고 이 값을 뷰에 전달
}
}
/*
* ModelAndView 정리
* setViewName(String view)
* - 응답할 view이름 설정
* - 페이지 이동값은 setViewName로 페이지를 세팅한다.
* addObject(String name, Object value)
* - view에 전달할 값을 설정
* - 데이터 추가는 addObject(key, value)로 추가하며
* addAllObject(Map values)
* - view에 전달할 값을 Map에 name-value로 저장하여 한번에 설정
*
* Model -> model.addAttribute를 사용하여 데이터만 저장
* vs ModelAndView -> 데이터와 이동하고자 하는 View Page를 같이 저장
*/
애플리케이션은 ManagerBase에서 해당 세션을 어떻게 찾아오는 것일까?
개발자 도구에서 쿠키를 보면 답을 알 수 있다.
HttpSession을 생성할 때, 톰캣에서 자동으로 랜덤한 문자열인 JSESSIONID를 생성한다. (2-3-4)
그리고 톰캣이 이 값을 쿠키에 담아 클라이언트에 전송한다.(5)
쿠키가 유지되는 동안 이 쿠키의 JSESSIONID 값으로 저장된 세션을 찾아온다. (6-7)
해당 쿠키를 삭제하면 새로운 세션에 연결되고 병아리의 수가 초기화된다.
세션은 JVM에 저장된다. 따라서 서버가 분산되어 있다면 위의 방식으로 동작하지 않는다. A서버 메모리의 세션 맵과 B서버 메모리의 세션 맵이 다르기 때문이다.
토큰 기반 인증은 사용자가 서버에서 발급받은 토큰을 요청마다 함께 주는 방식이다. 얼핏 보면 세션ID를 쿠키로 전달하는 것과 비슷해보이지만, 전달받은 값을 서버에서 처리하는 방식이 다르다.
Access Token
과 Refresh Token
을 함께 사용하는 경우에는 Refresh Token을 DB에 저장하게 된다.