@PostMapping("/login")
public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response) {
if (bindingResult.hasErrors()) return "login/loginForm";
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if (loginMember == null) {
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
return "login/loginForm";
}
//로그인 성공 처리
Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
return "redirect:/";
}
@PostMapping("/logout")
public String logout(HttpServletResponse response) {
expireCookie(response,"memberId");
return "redirect:/";
}
private void expireCookie(HttpServletResponse response,String cookieName) {
Cookie cookie = new Cookie(cookieName, null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
로그인 성공하면 웹브라우저 쿠키에 memberId=<MEMBERID>
를 설정한다.
로그아웃 시 memberId의 maxAge를 0으로 설정해 삭제한다.
위의 방식으로 로그인을 구현하면 악의적인 사용자가 브라우저의 쿠키를 조작해 다른 유저의 정보에 접근할 수 있다는 심각한 문제가 있다.
해결방안
세션 : 서버에 중요한 정보를 보관한고 연결을 유지하는 방법을 세션이라 한다.
서버는 서버 상에 위치한 세션 저장소에서 세션을 관리한다.
@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:/";
}
@PostMapping("/logout")
public String logoutV3(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if(session != null){
session.invalidate();
}
return "redirect:/";
}
로그인이 성공하면 member를 조회해 세션에 넣는다.
로그아웃 시 세션을 가져와 invalid로 만든다.
request.getSession()
default가 create=true, 이 경우 세션이 존재하지 않는 경우 새로 생성된다.
create=false 인 경우, 세션이 존재하지 않으면 null을 반환한다.
로그아웃을 하고 사이트를 나가는 사용자는 많이 없다. 대부분의 사용자들은 그냥 브라우저를 종료하거나 사이트를 나간다. 이럴 경우 서버는 사용자가 웹 사이트를 나갔는지 알지 못하기 때문에 세션을 계속 유지하면 세션 저장소는 점점 거대해진다.
이를 방지하기 위해서 세션에 마지막 접근 시간과 maxInactiveInterval을 이용해 일정 시간동안 접근하지 않은 세션을 삭제하는 식으로 세션을 관리한다.