Spring boot - 직접 Session Storage 구현하기
목차 Spring boot - HttpSession 사용하기 Spring boot - 직접 Session Storage 구현하기 Spring boot - Cookie 사용하기 직접 만든 Session 사용하기@Componentpublic class SessionManager { public static final String SESSION_COOKIE_NAME = "mySessionId"; private Map<String, Object> sessionStore = new ConcurrentHashMap<>(); public void createSession(Object value, HttpServletResponse response){ // Session id를 상성하고 값을 Session에 저장 String sessionId = UUID.randomUUID().toString(); // Session Store 에 새로운 Session 정보를 저장한다. // Session 은 Key Value 형태로 데이터를 저장 sessionStore.put(sessionId, value); // 쿠키 생성 // Session Id 를 Cookie 에 넣어 전달한다. Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId); response.addCookie(mySessionCookie); } public Object getSession(HttpServletRequest request){ // Request 에서 Session Id 를 가져온다. Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); if(sessionCookie == null){ return null; } // Session Store 에 저장된 Session 정보를 가져온다. return sessionStore.get(sessionCookie.getValue()); } public void expire(HttpServletRequest request){ Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); if(sessionCookie != null){ sessionStore.remove(sessionCookie.getValue()); } } public Cookie findCookie(HttpServletRequest request, String cookieName){ if(request.getCookies() == null){ return null; } return Arrays.stream(request.getCookies()) .filter(cookie -> cookie.getName().equals(cookieName)) .findAny() .orElse(null); }} @PostMapping("/login")public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){ log.info("Request Params : {}", form); if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 설공 처리 TODO // 쿠키 사용하기 // 쿠키에 시간 정보를 주지 않으면 세선 쿠(브라우저 종료시 모두 종료) Cookie cookie = new Cookie("memberId", String.valueOf(loginMember.getId())); response.addCookie(cookie); return "redirect:/";} Testclass SessionManagerTest { SessionManager sessionManager = new SessionManager(); @Test void SessionTest(){ // 세션 생성 MockHttpServletResponse response = new MockHttpServletResponse(); Member member = new Member(); sessionManager.createSession(member, response); // 요청에 응답 쿠키 저장 MockHttpServletRequest request = new MockHttpServletRequest(); request.setCookies(response.getCookies()); // 세션 조회 Object result = sessionManager.getSession(request); assertThat(result).isEqualTo(member); // 세션 만료 sessionManager.expire(request); Object expired = sessionManager.getSession(request); assertThat(expired).isNull(); }} @PostMapping("/login")public String loginV2(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){ log.info("Request Params : {}", form); if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 설공 처리 TODO // 세션 관리자를 통해 세션을 생성하고, 회원 데이터 보관 // 쿠키에 시간 정보를 주지 않으면 세션 쿠키(브라주어 종료시 모두 종료) sessionManager.createSession(loginMember, response); return "redirect:/";} @PostMapping("/logout")public String logoutV2(HttpServletRequest request){ sessionManager.expire(request); return "redirect:/";}