서블릿 Http 세션
쿠키를 이용해서 하는 것은 보안 문제가 있기 때문에 세션을 이용하는 것이 좋다. 세션이라는 것은 임의의 특이한 코드를 사용자에게 무작위로 줘서 고유의 값으로 서버와 연결할 수 있게 해주는 것이다.
서블릿에서 지원하는 세션 기능을 사용해서 구현할 수 있다.
@PostMapping("/login")
public String loginV3(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request) {
if (bindingResult.hasErrors()) {
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if (loginMember == null) {
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
return "login/loginForm";
}
// 로그인 성공 처리
// 세션이 있으면 있는 세션 반환, 없으면 신규 세션을 생성
HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return "redirect:/";
}
return 위의 두 줄이 지켜봐야 할 줄이다. HttpServletRequest를 가져와서 session에 request의 session을 넣고 setAttribute로 고유 세션 값을 넘겨준다.
@PostMapping("/logout")
public String logoutV3(HttpServletRequest request) {
HttpSession session = request.getSession(false); // true면 세션을 생성해주기 때문에 false
if (session != null) {
session.invalidate();
}
return "redirect:/";
}
로그아웃 할 때도 비슷한데 request.getSession()의 파라미터에 false를 넣어주는 이유는 true면 세션을 생성하기 때문에 이 때에는 확인하고 삭제 할 예정이기 때문에 false를 넣어줘야한다. 위의 로그인 세션에서 안 넣어준 이유는 true가 default 값이기 때문이다.
@GetMapping("/")
public String homeLoginV3(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false);
if (session == null) {
return "home";
}
Member loginMember = (Member)session.getAttribute(SessionConst.LOGIN_MEMBER);
// 세션에 회원 데이터가 없으면 home
if (loginMember == null) {
return "home";
}
// 세션이 유지되면 로그인으로 이동
model.addAttribute("member", loginMember);
return "loginHome";
}
홈 컨트롤러는 위와 같이 getSession을 false로 불러와서 session이 존재하지 않거나 회원 데이터가 없으면 home으로 가고 정상적으로 접근했으면 로그인 홈으로 넘기면서 모델에 attribute로 넘겨준다.
@GetMapping("/")
public String homeLoginV3Spring(@SessionAttribute(name = SessionConst.LOGIN_MEMBER,
required = false) Member loginMember, Model model) {
// 세션을 생성하지 않기 때문에 가져올때만 @SessionAttribute 사용
// 세션에 회원 데이터가 없으면 home
if (loginMember == null) {
return "home";
}
// 세션이 유지되면 로그인으로 이동
model.addAttribute("member", loginMember);
return "loginHome";
}
스플링에서 지원하는 @SessionAttribute를 사용하면 위의 코드를 더 간결하게 줄일 수 있다. 위의 복잡한 코드들이 다 생략되지만 세션을 생성하지 않기 때문에 세션을 가져올 때만 사용해야한다는 주의점이 있다.
세션 타임아웃
session.invalidate()가 호출되면 세션이 삭제된다. 하지만 사용자가 로그아웃을 안 누르고 웹 브라우저를 끈다면 세션이 삭제되지 않을 것이다. 그렇기 때문에 세션 타임아웃을 잘 걸어줘야한다.
application.properties에
server.servlet.session.timeout=1800
를 추가해주면 사용자의 마지막 요청으로부터 1800초(30분)동안 요청이 없으면 세션을 삭제한다.
사용자의 로그인이 아니라 마지막의 요청으로부터 시간이기 때문에 사용자의 이용이 끝나면 안전하게 세션을 삭제할 수 있다.